Quantcast
Channel: 俺的備忘録 〜なんかいろいろ〜
Viewing all 1028 articles
Browse latest View live

tarでアーカイブ作成時に特定のディレクトリ・ファイルを除外する

$
0
0

tarでアーカイブを作成する際、ディレクトリを指定してその配下全てをアーカイブ化することが多いだろう。
その中で、特定のサブディレクトリのみ除外してアーカイブを作成する場合は、「–exclude」オプションもしくは「-X」オプションを付与すると良いだろう。

1.「–exclude」オプション

コマンドラインで直接PATHを指定する場合は、「–exclude」オプションを付与する。

tar cvf --exclude 除外ディレクトリのPATH アーカイブ対象ディレクトリ

20151112_000003

[root@test-centos7 ~]# find /work8 -type d
/work8
/work8/work8-1
/work8/work8-1/8-1-2
/work8/work8-1/8-1-3
/work8/work8-1/8-1-4
/work8/work8-2
/work8/work8-2/8-2-4
/work8/work8-2/8-2-2
/work8/work8-3
/work8/work8-4
/work8/work8-4/8-4-2
/work8/work8-4/8-4-1
/work8/work8-4/8-4-7
/work8/work8-5
/work8/work8-6
[root@test-centos7 ~]# tar czvf /tmp/test8.tar.gz --exclude /work8/work8-1 /work8
tar: メンバ名から先頭の `/' を取り除きます
/work8/
/work8/work8-2/
/work8/work8-2/8-2-4/
/work8/work8-2/8-2-2/
/work8/work8-3/
/work8/work8-4/
/work8/work8-4/8-4-2/
/work8/work8-4/8-4-1/
/work8/work8-4/8-4-7/
/work8/work8-5/
/work8/work8-6/

 

なお、複数ディレクトリを除外する場合は「–exclude」を別途記述して指定する必要がある。

20151112_000004

[root@test-centos7 ~]# tar czvf /tmp/test8.tar.gz --exclude /work8/work8-1 --exclude /work8/work8-2 /work8
tar: メンバ名から先頭の `/' を取り除きます
/work8/
/work8/work8-3/
/work8/work8-4/
/work8/work8-4/8-4-2/
/work8/work8-4/8-4-1/
/work8/work8-4/8-4-7/
/work8/work8-5/
/work8/work8-6/

2.「-X」オプション

「-X」オプションを使用すると、ファイルに記述されているPATHを除外してアーカイブファイルを作成することが出来る。

tar cvf -X 除外ディレクトリのPATHを書いたファイル アーカイブ対象ディレクトリ

20151112_000005

[root@test-centos7 ~]# cat /tmp/work8.list
/work8/work8-4
/work8/work8-5

[root@test-centos7 ~]# tar czvf /tmp/test8.tar.gz -X /tmp/work8.list /work8
tar: メンバ名から先頭の `/' を取り除きます
/work8/
/work8/work8-1/
/work8/work8-1/8-1-2/
/work8/work8-1/8-1-3/
/work8/work8-1/8-1-4/
/work8/work8-2/
/work8/work8-2/8-2-4/
/work8/work8-2/8-2-2/
/work8/work8-3/
/work8/work8-6/

 

新しいLinuxの教科書 新しいLinuxの教科書

ApacheのリバースプロキシサーバでバックのWEBサーバをまとめてBasic認証をさせる

$
0
0

少し前に、今いるプロジェクトでApacheによるリバースプロキシでのBasic認証を設定する事があったので、その備忘。
ApacheのProxyでBasic認証を処理させる場合は、以下の例ようにhttpd.conf(というか、最近ではそれをIncludeしている設定ファイル)で記述してあげればいい。

●httpd.conf(VirtualHost配下で指定している)

<VirtualHost*:80>
    ...
    <Proxy>
        AuthType Basic
        AuthName "..."
        Order deny,allow
        Allow from all
        ...
    </Proxy>    
    ...
<VirtualHost*:80>

 

できるPRO Apache Webサーバー 改訂版 Version 2.4/2.2/2.0対応 (できるPROシリーズ) できるPRO Apache Webサーバー 改訂版 Version 2.4/2.2/2.0対応 (できるPROシリーズ)

シェルスクリプトで日付が月末日かどうかを判定する

$
0
0

時折、ログのアーカイブなどで当日が月末か否かでスクリプトの処理を変えさせる必要があったりする。
シェルスクリプトで対象の日付が月末か否かを判断させる場合、以下のようにすると良いだろう。

get_date=`date +%d -d '1 day'`
if [ $get_date = "01" ];then
    echo "月末です"
fi

 

まぁ、単純にdateコマンドで日だけを取得して1日足して、その値が”01″であれば月末であることを把握するという内容。
同様に、当日が月初か否かもこれで取得出来る。

UNIXシェルスクリプト マスターピース132 UNIXシェルスクリプト マスターピース132

ncコマンドを使って、ミドルウェアのインストール前に疎通確認を行えるようにする

$
0
0

Linuxサーバで、ミドルウェアインストール前にネットワークの疎通確認を行う場合、ncコマンドが入っていれば簡易的なTCP/UDPサーバを立ち上げてポートを開けて確認を行う事が出来る。

TCPの場合は、待受側で以下のようにコマンドを実行する。

nc -vkl ポート番号

UDPの場合、keepaliveオプションが無いため、catを使って無理やり受信を続けさせる。
そのため、待受側では以下のようにコマンドを実行する。

nc -e /bin/cat -kuvl ポート番号

 

これで簡易TCP/UDPサーバが出来上がった。
送信側は、echoと組み合わせ文字列を送信させる事でテスト出来る。

echo "test" | nc IPアドレス ポート番号 #TCP側テスト
echo "test" | nc -u IPアドレス ポート番号 #UDP側テスト
ネットワークエンジニアの教科書 ネットワークエンジニアの教科書

nc(netcat)コマンドで覚えておきたい使い方8個

$
0
0

Linuxでポートの疎通確認を行う際によく用いるncコマンド。
今回は、このncコマンドで覚えておきたい使い方についてまとめてみる事にする。

使用したのは、Ubuntu 14.04 LTSに入っている以下のもの。

20151116_000001

test@test-vm-ubuntu:~$ nc --help
nc: invalid option -- '-'
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46bCDdhjklnrStUuvZz] [-I length] [-i interval] [-O length]
          [-P proxy_username] [-p source_port] [-q seconds] [-s source]
          [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]
          [-x proxy_address[:port]] [destination] [port]

 

1.基本的な使い方・クライアントとして動作させる

ncコマンドで最もよく使われる使い方としては、対象ホストに対してポート指定をして、クライアントとして疎通確認を行うというものだろう。
基本的には、以下のようにコマンドを実行する。

nc 対象ホスト(IPアドレス等) ポート番号

TCPではなく、UDPでの疎通を確認する場合は「-u」オプションを付与する。

nc -u 対象ホスト(IPアドレス等) ポート番号

 

ただポート確認を行うだけではなく、ヘッダを相手先ポートに送りつける事でその後の処理を実施させることも出来る。
例えば、以下のようにコマンドを実行することでwebサーバへhttp-getリクエストを行う事ができる。

echo -en "GET / HTTP/1.1\n\n" | nc 対象ホスト(IPアドレス等) 80

 

 

2.基本的な使い方・サーバとして動作させる

ncでポートの待受側(サーバ側)として動作させる場合は、以下のように「-l」オプションを付与する。

nc -l ポート番号 # TCPのポート番号で待ち受ける
nc -ul ポート番号 # UDPのポート番号で 待ち受ける

 

ただし、上記のコマンドだと一度疎通に成功するとサーバ側のプロセスが終了してしまう。
サーバ側で明示的にプロセスを終了するまでポートを開けさせたい場合は、TCPの場合は「-k」を、UDPの場合は「-e ‘cat’」でポートを開けさせておく事が出来る。

nc -kvl ポート番号 #TCP
nc -e /bin/cat -uvl ポート番号 # UDP

 

なお、CentOSやUbuntuのパッケージからインストールしたり、バンドルされているコマンドの場合、「-e」オプションが利用出来ないようにしてる可能性がある。
この場合は、別途ソースからインストールして-eオプションを使えるようにしてあげる必要があるので注意。

 

3.ファイルを転送する

ncコマンドでは、FTPやscpを使わずにクライアント⇔サーバ間で直接ファイルを転送することも出来る。
(セキュリティ考慮する必要がある環境ではおすすめしないけど)

 

●サーバ側からクライアント側にファイルを取得させる場合

nc -l ポート番号 < 転送するファイルPATH # サーバ側
nc 対象ホスト(IPアドレス等) ポート番号 > 転送されたファイルを取得するPATH # クライアント側

 

画像は、左がサーバ側、右がクライアント側のコンソール。
サーバ側でリダイレクトしてたアーカイブファイルが、無事クライアント側で取得、展開出来ている事がわかる。

20151116_000003

 

●クライアント側からサーバ側にファイルを取得させる場合

nc -l ポート番号 > 取得したファイルの保持先PATH # サーバ側
nc 対象ホスト(IPアドレス等) ポート番号 < 転送するファイルPATH # クライアント側

4.IPv4、IPv6を指定する

IPv4の場合は「-4」、IPv6の場合は「-6」を付与することで通信を可能にする。
なお、デフォルトはIPv4。

20151116_000004

test@test-vm-ubuntu:~$ # オプション無し
test@test-vm-ubuntu:~$ nc -l 55551 &
[2] 6013
test@test-vm-ubuntu:~$
test@test-vm-ubuntu:~$ # IPv4
test@test-vm-ubuntu:~$ nc -l4 55552 &
[3] 6014
test@test-vm-ubuntu:~$
test@test-vm-ubuntu:~$ # IPv6
test@test-vm-ubuntu:~$ nc -l6 55553 &
[4] 6015
test@test-vm-ubuntu:~$
test@test-vm-ubuntu:~$ netstat -an | grep 5555[1-3]
tcp        0      0 0.0.0.0:55551           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:55552           0.0.0.0:*               LISTEN
tcp6       0      0 :::55553                :::*                    LISTEN

 

5.通信の詳細を取得する

通信の詳細を表示させる場合は「-v」オプションを付与する。

 

6.ソースアドレス・ポートを指定する

パケット送信側のホストに割り当てられているIPアドレスであれば、「-s」でアドレスを指定して通信を行わせる事も出来る。
送信側のポートを指定する場合は、「-p」で指定できる。

nc -s ホストに割り当てられているIPアドレス -p 送信時のポート番号 対象ホスト ポート番号

 

7.ポート範囲を指定してスキャンを行う

nc(netcat)には、「-z」というポートの確認だけをするオプションが存在する。
これと「-v」オプションを組み合わせる事で、対象ホストでListenしているポートを確認することが出来る。

nc -vz 対象ホスト ポート番号-ポート番号

 

以下の例は、対象のホストで4440-4450の範囲で開いているポートを確認している。

20151116_000005

 

8.ポートへのアクセス時にコマンド(bash等)が実行されるようにする

「-e」オプションを使用することにより、サーバ側で特定のコマンドを実行させることが出来る。
なお、セキュリティの観点からか、UbuntuやCentOSでパッケージからインストールしたコマンドだとこのオプションは使えない。そのため、別途ソースからインストールするなどが必要となる。

nc -l -e 'コマンド' ポート番号

以下の例では、右のサーバ側でbashを待ち受けている。
プロンプトは表示されないが、サーバ側をコマンドで操作出来ている事がわかる。
…まぁ、普通にバックドアですよね、これ。

20151116_000007

 

とりあえず、以上8個を紹介させてもらった。
実際にはまだまだ面白い使い方はあるだろうし、見つけたらまた追記していくことにする。

ネットワークエンジニアの教科書 ネットワークエンジニアの教科書

数字を人の読みやすいように加工する『numfmt』コマンド

$
0
0

シェルスクリプトやCUIでLinuxを操作していると、バイトで記述された容量を人が読みやすい状態に加工したい時がある。
それを簡単に行えるのが、Coreutils 8.22から追加された『numfmt』コマンドだ。

少なくとも、CentOS 7やUbuntu 14.04 LTSでは標準で利用することが出来る。

このコマンドの使い方については、もう見てもらった方が早いだろう。
以下のようにechoで「4096000(4MB相当)」を出力し、それをnumfmtに渡す。すると…

echo 4096000 | numfmt --to=iec

20151118_000013

[root@test-apache ~]# echo 4096000
4096000
[root@test-apache ~]# echo 4096000 | numfmt --to=iec
4.0M

 

このように、人が見てわかりやすい容量に加工してくれるのだ。
区切り文字や何列目の数字を加工するかについても指定できて、地味にかなり便利なコマンド。

もちろん、計算方法も1000で単位を上げるのか、1024で単位を上げるのか「–to=UNIT」で指定可能だ。
以下、指定できるUNITについて、helpの内容を一部抜粋する。

UNIT options:
  none       no auto-scaling is done; suffixes will trigger an error
  auto       accept optional single/two letter suffix:
               1K = 1000,
               1Ki = 1024,
               1M = 1000000,
               1Mi = 1048576,
  si         accept optional single letter suffix:
               1K = 1000,
               1M = 1000000,
               ...
  iec        accept optional single letter suffix:
               1K = 1024,
               1M = 1048576,
               ...
  iec-i      accept optional two-letter suffix:
               1Ki = 1024,
               1Mi = 1048576,
               ...

基本的には、バイト数を計算させるならば「iec」「iec-i」を使えばいいだろう。

その他、こんな事もできる。
例えば、以前こちらで紹介したLinuxの特定ディレクトリ配下で容量を食ってるファイルTOP10を抽出するコマンドと組み合わせると…

ls -la $(find /調べたいディレクトリ -type f) | sort -nr -k5 | head -10 #既存のコマンド
ls -la $(find /調べたいディレクトリ -type f) | sort -nr -k5 | head -10 | numfmt --to=iec --field=5 # numfmtで加工する

20151118_000014

[root@test-centos7 ~]# ls -la $(find /work -type f) | sort -nr -k5 | head -10
-rw-r--r--. 1 root   root   1024000000  7月 26 11:29 /work/test2.bk
-rw-r--r--. 1 root   root   1024000000  7月 26 11:29 /work/test1.bk
-rw-r--r--. 1 root   root   1024000000  7月 11 05:13 /work/test2
-rw-r--r--. 1 root   root   1024000000  7月 11 05:12 /work/test1
-rw-r--r--. 1 root   root    209715200  7月 26 11:28 /work/sample.bk
-rw-r--r--. 1 root   root    209715200  6月  8 23:12 /work/sample
-rw-r--r--. 1 root   root     36814848  7月 26 11:28 /work/test.image.bk
-rw-r--r--. 1 root   root     36814848  6月 20 19:37 /work/test.image
-rw-r--r--. 1 root   root        99973 11月 16 11:44 /work/20151113_134734_AWSテスト.log
-rw-r--r--. 1 root   root        64368 10月 27 06:44 /work/test7_2.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# ls -la $(find /work -type f) | sort -nr -k5 | head -10 | numfmt --to=iec --field=5
-rw-r--r--. 1 root   root         977M  7月 26 11:29 /work/test2.bk
-rw-r--r--. 1 root   root         977M  7月 26 11:29 /work/test1.bk
-rw-r--r--. 1 root   root         977M  7月 11 05:13 /work/test2
-rw-r--r--. 1 root   root         977M  7月 11 05:12 /work/test1
-rw-r--r--. 1 root   root         200M  7月 26 11:28 /work/sample.bk
-rw-r--r--. 1 root   root         200M  6月  8 23:12 /work/sample
-rw-r--r--. 1 root   root          36M  7月 26 11:28 /work/test.image.bk
-rw-r--r--. 1 root   root          36M  6月 20 19:37 /work/test.image
-rw-r--r--. 1 root   root          98K 11月 16 11:44 /work/20151113_134734_AWSテスト.log
-rw-r--r--. 1 root   root          63K 10月 27 06:44 /work/test7_2.sh

 

このように、一度容量順でソートした後でも人の見やすい形式に直す事が出来る。
上の例では空白区切り(デフォルト)の5列目を指定しているが、区切り文字も「–delimiter」オプションで指定可能だ。

細かいオプションや使い方については、また後日まとめてみるかもだが、これは非常に便利なコマンドだ。

CentOS7システム管理ガイドsystemd/NetworkManager/Firewalld徹底攻略 CentOS7システム管理ガイドsystemd/NetworkManager/Firewalld徹底攻略

linuxで指定したファイルの合計サイズを取得する

$
0
0

linuxで、ディレクトリ内のファイルの合計容量を取得するのではなく、個別に指定したファイル(ワイルドカードで拡張子等を指定したファイルなど)の合計サイズを取得する場合、大まかに分けて2つの方法がある。

1.ls(find)とawkで容量の合計を計算する

ls(+find)とawkで、指定したファイルの合計容量を取得することができる。
lsの実行結果を、awkコマンドで加工する事で合計容量の取得を行えば良い。計算対象をうまく記述出来なければ、ファイルにPATHを記述して$(cat ファイル)で読み出せば良い。

もしCentOS7もしくはUbuntu 14.04以降のOSで、かつ人の読みやすい出力形式にしたいならば、「numfmt」コマンドで加工してあげると良いだろう。

ls -la ファイルPATH等条件 | awk '{ total += $5 }; END { print total }'

20151118_000012

[root@test-centos7 ~]# ls -la /work/test*.py
-rw-r--r--. 1 root root 2223 10月 27 07:10 /work/test.py
-rw-r--r--. 1 root root  457 10月 28 20:09 /work/test1.py
-rw-r--r--. 1 root root 3261 10月 28 22:27 /work/test10.py
-rw-r--r--. 1 root root 1567 10月 28 22:26 /work/test11.py
-rwxr-xr-x. 1 root root 4450 11月  3 07:36 /work/test12.py
-rw-r--r--. 1 root root  682 10月 31 11:09 /work/test13.py
-rw-r--r--. 1 root root  505 11月  6 07:02 /work/test14.py
-rw-r--r--. 1 root root  347 11月  5 06:59 /work/test15.py
-rw-r--r--. 1 root root  232 11月  5 07:04 /work/test16.py
-rw-r--r--. 1 root root 1983 11月  6 08:10 /work/test17.py
-rw-r--r--. 1 root root  649 11月  6 15:37 /work/test18.py
-rw-r--r--. 1 root root  904 11月 11 07:15 /work/test19.py
-rw-r--r--. 1 root root 1345 10月 27 07:06 /work/test2.py
-rw-r--r--. 1 root root 1040 11月 12 13:01 /work/test20.py
-rw-r--r--. 1 root root 1028 11月 12 13:03 /work/test21.py
-rw-r--r--. 1 root root   65 11月 12 17:36 /work/test22.py
-rw-r--r--. 1 root root 1254 11月 12 17:49 /work/test23.py
-rw-r--r--. 1 root root 3310 10月 28 20:10 /work/test3.py
-rw-r--r--. 1 root root 7878 10月 28 20:21 /work/test4.py
-rw-r--r--. 1 root root 1299 10月 28 20:22 /work/test5.py
-rw-r--r--. 1 root root 8432 10月 28 20:54 /work/test6.py
-rw-r--r--. 1 root root  313 10月 28 22:20 /work/test7.py
-rw-r--r--. 1 root root 2887 10月 28 22:22 /work/test8.py
-rw-r--r--. 1 root root 4991 10月 28 22:23 /work/test9.py
[root@test-centos7 ~]# ls -la /work/test*.py | awk '{ total += $5 }; END { print total }'
51102
[root@test-centos7 ~]# ls -la /work/test*.py | awk '{ total += $5 }; END { print total }' | numfmt --to=iec
50K

2.du(or 「wc -c」)で取得する

その他、duもしくは「wc -c」で合計容量を取得する方法もある。
こちらは、合計のみを取得したい場合はtailと組み合わせる必要があるが、「-bh」を付与することで人が読みやすい形式に出力することができる。
(「wc -c」の場合は単位がバイトなので、numfmtで読みやすいよう加工する等が必要になる)

du -bhc ファイルPATH等条件 | tail -n 1

20151118_000015

[root@test-centos7 ~]# du -bhc /work/test*.py
2.2K    /work/test.py
457     /work/test1.py
3.2K    /work/test10.py
1.6K    /work/test11.py
4.4K    /work/test12.py
682     /work/test13.py
505     /work/test14.py
347     /work/test15.py
232     /work/test16.py
2.0K    /work/test17.py
649     /work/test18.py
904     /work/test19.py
1.4K    /work/test2.py
1.1K    /work/test20.py
1.1K    /work/test21.py
65      /work/test22.py
1.3K    /work/test23.py
3.3K    /work/test3.py
7.7K    /work/test4.py
1.3K    /work/test5.py
8.3K    /work/test6.py
313     /work/test7.py
2.9K    /work/test8.py
4.9K    /work/test9.py
50K     合計
[root@test-centos7 ~]# du -bhc /work/test*.py | tail -n 1
50K     合計

 

以上、2つの手法について紹介させてもらった。
ファイルをアーカイブ化する前に、元ファイルがどの程度の容量だったのかみるときなどに有効だろう。

 

Linux完全マスターバイブル (100%ムックシリーズ) Linux完全マスターバイブル (100%ムックシリーズ)

ヌルコマンドでシェルスクリプトの変数が空の場合に特定の値を代入させる

$
0
0

シェルスクリプトを書いていると、特定の変数の値が空(NULL)の時はデフォルト値を代入する処理を行う必要が出てくる事がある。
そんなときは、ヌルコマンドで変数が空の時はデフォルト値を代入するように記述すると良いだろう。

変数の値が空の時にデフォルト値を代入する場合は、以下のように記述する。

: ${変数:=デフォルト値}

 

以下の例では、引数を代入する変数『TEST_VAR』に値がない場合、デフォルト値として『DEFAULT_123』という値を代入する

#!/bin/sh
TEST_VAR=$1
: ${TEST_VAR:='DEFAULT_123'}

echo $TEST_VAR

20151117_000000

[root@test-centos7 ~]# cat /work/TEST1.sh
#!/bin/sh
TEST_VAR=$1
: ${TEST_VAR:='DEFAULT_123'}

echo $TEST_VAR
[root@test-centos7 ~]# sh /work/TEST1.sh 123
123
[root@test-centos7 ~]# sh /work/TEST1.sh
DEFAULT_123

 

その他、ヌルコマンドでは以下のような使い方が出来るようだ。

●一時的な代入(変数に対し値の代入までは行わない)

変数が空(NULL)は一時的な代入を行い、その後の変数にまで影響しない場合は、「${変数:-代入値}」と記述する。
例として、以下のようなスクリプトを実行する。

#!/bin/sh
TEST_VAR=$1

echo "#変数が空の時"
echo ${TEST_VAR:-'DEFAULT_123'}
echo ""

echo "#再度呼び出す"
echo $TEST_VAR
echo ""

20151117_000001

[root@test-centos7 ~]# cat /work/TEST2.sh
#!/bin/sh
TEST_VAR=$1

echo "#変数が空の時"
echo ${TEST_VAR:-'DEFAULT_123'}
echo ""

echo "#再度呼び出す"
echo $TEST_VAR
echo ""
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/TEST2.sh
#変数が空の時
DEFAULT_123

#再度呼び出す


[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/TEST2.sh 1
#変数が空の時
1

#再度呼び出す
1

 

●変数が空(NULL)の場合はNULLを、値が入っている場合は別の値を返す

変数が空(NULL)の場合にはそのままNULLを、値が代入されている場合のみ別の値を代入することもできる。
その場合は、「${変数:+代入値}」と記述すればよい。なお、この時変数に値は代入されないので注意。

以下、例となるスクリプトとその実行結果を記述しておく。

#!/bin/sh
TEST_VAR=$1

echo "#変数が空ではない時"
echo ${TEST_VAR:+'DEFAULT_123'}
echo ""

echo "#再度呼び出す"
echo $TEST_VAR
echo ""

20151117_000002

[root@test-centos7 ~]# cat /work/TEST3.sh
#!/bin/sh
TEST_VAR=$1

echo "#変数が空ではない時"
echo ${TEST_VAR:+'DEFAULT_123'}
echo ""

echo "#再度呼び出す"
echo $TEST_VAR
echo ""
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/TEST3.sh 123
#変数が空ではない時
DEFAULT_123

#再度呼び出す
123

[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/TEST3.sh
#変数が空ではない時


#再度呼び出す

 

●変数が空(NULL)の場合はエラー終了する

変数が空の場合、その箇所でスクリプトをエラー終了させることも出来る。
その場合は、「${変数:?エラーメッセージ}」というように記述する。

以下、スクリプト例。

#!/bin/sh
TEST_VAR=$1
: ${TEST_VAR:?"変数がNULLです"}

echo $TEST_VAR

20151117_000003

[root@test-centos7 ~]# cat /work/TEST4.sh
#!/bin/sh
TEST_VAR=$1
: ${TEST_VAR:?"変数がNULLです"}

echo $TEST_VAR
[root@test-centos7 ~]#
[root@test-centos7 ~]# # 変数がNULLの場合
[root@test-centos7 ~]# sh /work/TEST4.sh
/work/TEST4.sh: 行 3: TEST_VAR: 変数がNULLです
[root@test-centos7 ~]#
[root@test-centos7 ~]# # 変数がNULLではない場合
[root@test-centos7 ~]# sh /work/TEST4.sh 12345
12345

 

うまく使いこなせれば、スクリプトの記述量も少なくできそうだ。

UNIXシェルスクリプト マスターピース132 UNIXシェルスクリプト マスターピース132

Linuxのzip/unzipコマンドで覚えておきたい使い方11個

$
0
0

Linuxでzipファイルを扱う際、欠かせないのがzip/unzipコマンド。
今回は、このコマンドについて覚えておきたい使い方について紹介しておく。

1.基本的な使い方

基本的には、zipファイルとして圧縮もしくは解凍する際は以下のようにコマンドを実行する。

zip 作成するZIPファイルPATH 圧縮対象PATH ... # 圧縮時
unzip 解凍するZIPファイルPATH # 解凍時

20151117_000004

[root@test-centos7 ~]# zip /tmp/test1.zip /work3/TEST1.sh /work3/TEST2.sh
  adding: work3/TEST1.sh (deflated 16%)
  adding: work3/TEST2.sh (deflated 27%)
[root@test-centos7 ~]#
[root@test-centos7 ~]# unzip /tmp/test1.zip
Archive:  /tmp/test1.zip
  inflating: work3/TEST1.sh
  inflating: work3/TEST2.sh

 

なお、作成するファイルPATHに既存のzipファイルを指定すると、ファイルのUPDATE及び追加をデフォルトで行ってくれる。
(削除はしない)

20151117_000006

[root@test-centos7 ~]# zip /tmp/test1.zip /work3/TEST1.sh /work3/TEST2.sh
  adding: work3/TEST1.sh (deflated 16%)
  adding: work3/TEST2.sh (deflated 27%)
[root@test-centos7 ~]# ls -la /tmp/test1.zip
-rw-r--r--. 1 root root 493 11月 17 06:24 /tmp/test1.zip
[root@test-centos7 ~]# zip /tmp/test1.zip /work3/TEST1.sh /work3/TEST2.sh /work3/TEST3.sh
updating: work3/TEST1.sh (deflated 16%)
updating: work3/TEST2.sh (deflated 27%)
  adding: work3/TEST3.sh (deflated 25%)
[root@test-centos7 ~]# ls -la /tmp/test1.zip
-rw-r--r--. 1 root root 762 11月 17 06:24 /tmp/test1.zip

 

2.ディレクトリを指定して再帰的に圧縮する

オプション無しの場合、zipコマンドではディレクトリのみを指定すると中のファイルは圧縮してくれない。
ディレクトリ配下を再帰的に圧縮する場合は、「-r」オプションを付与する。

zip -r 作成するzipファイルPATH 再帰的に圧縮するフォルダ

20151117_000005

[root@test-centos7 ~]# zip -r /tmp/test1.zip /work3/
updating: work3/TEST1.sh (deflated 16%)
updating: work3/TEST2.sh (deflated 27%)
  adding: work3/ (stored 0%)
  adding: work3/work/ (stored 0%)
  adding: work3/work/ln_test.txt (deflated 46%)
  adding: work3/work/ln_test.txt2 (deflated 46%)
  adding: work3/work/aaaaa.txt (stored 0%)
  adding: work3/work/bbbbb.txt (stored 0%)
  adding: work3/work/ccccc.txt (stored 0%)
  adding: work3/work/ddddd.txt (stored 0%)
  adding: work3/work/test.txt (deflated 46%)
  adding: work3/work/test2.txt (deflated 69%)
  adding: work3/aaaaa.txt (stored 0%)
  adding: work3/bbbbb.txt (stored 0%)
  adding: work3/ccccc.txt (stored 0%)
  adding: work3/ln_aaaaa.txt (stored 0%)
  ...

 

3.圧縮対象となるファイル名を指定して圧縮する

特定の拡張子のファイルのみを圧縮する場合は、「-i」オプションをコマンドの末尾に付与する。
なお、指定できるファイル名はpathである点に注意。ファイル名だけで圧縮が出来ないので、基本的にはワイルドカードと組み合わせて使用する。

zip 作成するZIPファイルPATH 圧縮対象PATH ... -i 圧縮対象ファイル名

20151117_000007

[root@test-centos7 ~]# zip -r /tmp/test1.zip /work3/ -i *test*.py
  adding: work3/test.py (deflated 65%)
  adding: work3/test1.py (deflated 51%)
  adding: work3/test10.py (deflated 73%)
  adding: work3/test11.py (deflated 59%)
  adding: work3/test12.py (deflated 71%)
  adding: work3/test13.py (deflated 60%)
  adding: work3/test14.py (deflated 45%)
  adding: work3/test15.py (deflated 35%)
  ...

 

4.zipファイルの解凍先を指定する

unzipで解凍先のPATHを指定する場合は、「-d」オプションで解凍先PATHを指定することで行える。

unzip 解凍するZIPファイルPATH -d 解凍先PATH

20151117_000008

[root@test-centos7 ~]# mkdir /tmp/test1233
[root@test-centos7 ~]# unzip /tmp/test1.zip -d /tmp/test1233
Archive:  /tmp/test1.zip
  inflating: /tmp/test1233/work3/test.py
  inflating: /tmp/test1233/work3/test1.py
  inflating: /tmp/test1233/work3/test10.py
  inflating: /tmp/test1233/work3/test11.py
  inflating: /tmp/test1233/work3/test12.py
  inflating: /tmp/test1233/work3/test13.py
  inflating: /tmp/test1233/work3/test14.py
  inflating: /tmp/test1233/work3/test15.py
  ...

 

5.パスワードを指定して圧縮する

zipコマンドでは、「-e」オプションを付与することで圧縮ファイルにパスワードを付与することも出来る。

zip -e 作成するZIPファイルPATH 圧縮対象PATH ...

20151118_000000

[root@test-centos7 ~]# zip -er /tmp/test1.zip /work3/ -i *test1*.py
Enter password:
Verify password:
  adding: work3/test1.py (deflated 51%)
  adding: work3/test10.py (deflated 73%)
  adding: work3/test11.py (deflated 59%)
  adding: work3/test12.py (deflated 71%)
  adding: work3/test13.py (deflated 60%)
  adding: work3/test14.py (deflated 45%)
  adding: work3/test15.py (deflated 35%)
  adding: work3/test16.py (deflated 29%)
  adding: work3/test17.py (deflated 66%)
  adding: work3/test18.py (deflated 43%)
  adding: work3/test19.py (deflated 57%)
[root@test-centos7 ~]#
[root@test-centos7 ~]# unzip /tmp/test1.zip
Archive:  /tmp/test1.zip
[/tmp/test1.zip] work3/test1.py password:
  inflating: work3/test1.py
  inflating: work3/test10.py
  inflating: work3/test11.py
  inflating: work3/test12.py
  inflating: work3/test13.py
  inflating: work3/test14.py
  inflating: work3/test15.py
  inflating: work3/test16.py
  inflating: work3/test17.py
  inflating: work3/test18.py
  inflating: work3/test19.py

6.zipファイルの中身を確認する

zipファイルの中身を確認する場合は、unzipコマンドで「-l」オプションを使用すると良いだろう。

unzip -l 対象となるzipファイルのPATH

20151118_000001

[root@test-centos7 ~]# unzip -l /tmp/test1.zip
Archive:  /tmp/test1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      457  11-17-2015 06:02   work3/test1.py
     3261  11-17-2015 06:02   work3/test10.py
     1567  11-17-2015 06:02   work3/test11.py
     4450  11-17-2015 06:02   work3/test12.py
      682  11-17-2015 06:02   work3/test13.py
      505  11-17-2015 06:02   work3/test14.py
      347  11-17-2015 06:02   work3/test15.py
      232  11-17-2015 06:02   work3/test16.py
     1983  11-17-2015 06:02   work3/test17.py
      649  11-17-2015 06:02   work3/test18.py
      904  11-17-2015 06:02   work3/test19.py
---------                     -------
    15037                     11 files

 

7.既存のzipファイルにファイルを追加・更新する

既存のzipファイルに対して、ファイルを追加する場合はオプション無しで追加・更新が可能である。

20151118_000003

[root@test-centos7 ~]# zip -r /tmp/test1.zip /work3/ -i *test1?.py
  adding: work3/test10.py (deflated 73%)
  adding: work3/test11.py (deflated 59%)
  adding: work3/test12.py (deflated 71%)
  adding: work3/test13.py (deflated 60%)
  adding: work3/test14.py (deflated 45%)
  adding: work3/test15.py (deflated 35%)
  adding: work3/test16.py (deflated 29%)
  adding: work3/test17.py (deflated 66%)
  adding: work3/test18.py (deflated 43%)
  adding: work3/test19.py (deflated 57%)
[root@test-centos7 ~]# zip -r /tmp/test1.zip /work3/ -i *test1*.py
updating: work3/test10.py (deflated 73%)
updating: work3/test11.py (deflated 59%)
updating: work3/test12.py (deflated 71%)
updating: work3/test13.py (deflated 60%)
updating: work3/test14.py (deflated 45%)
updating: work3/test15.py (deflated 35%)
updating: work3/test16.py (deflated 29%)
updating: work3/test17.py (deflated 66%)
updating: work3/test18.py (deflated 43%)
updating: work3/test19.py (deflated 57%)
  adding: work3/test1.py (deflated 51%)

 

変動のあったファイルのみを置き換えるする(新規追加もしない)場合は、「-f」オプションを、変動のあったファイルおよび新規のファイルのみを追加する場合は「-u」オプションを付与する。

zip -f 対象となるZIPファイルPATH 圧縮対象PATH ... # 変動のあったファイルのみ置き換える(新規ファイルは追加しない)
zip -u 対象となるZIPファイルPATH 圧縮対象PATH ... # 変動のあったファイルおよび新規ファイルを更新・追加する

20151118_000005

[root@test-centos7 ~]# zip -r /tmp/test1.zip /work3/ -i *test1*.py
  adding: work3/test1.py (deflated 51%)
  adding: work3/test10.py (deflated 73%)
  adding: work3/test11.py (deflated 59%)
  adding: work3/test12.py (deflated 71%)
  adding: work3/test13.py (deflated 60%)
  adding: work3/test14.py (deflated 45%)
  adding: work3/test15.py (deflated 35%)
  adding: work3/test16.py (deflated 30%)
  adding: work3/test17.py (deflated 66%)
  adding: work3/test18.py (deflated 43%)
  adding: work3/test19.py (deflated 57%)
[root@test-centos7 ~]#
[root@test-centos7 ~]# echo "aaaaa" >> /work3/test12.py
[root@test-centos7 ~]# zip -fr /tmp/test1.zip /work3/ -i *test*.py
freshening: work3/test12.py (deflated 71%)
[root@test-centos7 ~]#
[root@test-centos7 ~]# echo "aaaaa" >> /work3/test16.py
[root@test-centos7 ~]# zip -ur /tmp/test1.zip /work3/ -i *test*.py
updating: work3/test16.py (deflated 31%)
  adding: work3/test.py (deflated 65%)
  adding: work3/test2.py (deflated 63%)
  adding: work3/test20.py (deflated 50%)
  adding: work3/test21.py (deflated 70%)
  adding: work3/test22.py (deflated 25%)
  adding: work3/test23.py (deflated 57%)
  adding: work3/test3.py (deflated 69%)
  adding: work3/test4.py (deflated 71%)
  adding: work3/test5.py (deflated 62%)
  adding: work3/test6.py (deflated 72%)
  adding: work3/test7.py (deflated 42%)
  adding: work3/test8.py (deflated 64%)
  adding: work3/test9.py (deflated 84%)

 

8.既存のzipファイルから一部を削除する

既存のzipファイルから中のファイルを一部削除する場合、zipコマンドで「-d」オプションを用いる。

zip -d 対象となるzipファイルのPATH -d 削除対象ファイルのPATH

20151118_000006

[root@test-centos7 ~]# unzip -l /tmp/test1.zip
Archive:  /tmp/test1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      457  11-17-2015 06:02   work3/test1.py
     3261  11-17-2015 06:02   work3/test10.py
     1567  11-17-2015 06:02   work3/test11.py
      694  11-18-2015 05:06   work3/test13.py
      347  11-17-2015 06:02   work3/test15.py
      244  11-18-2015 05:08   work3/test16.py
     1983  11-17-2015 06:02   work3/test17.py
      649  11-17-2015 06:02   work3/test18.py
      904  11-17-2015 06:02   work3/test19.py
---------                     -------
    10106                     9 files
[root@test-centos7 ~]# zip -d /tmp/test1.zip work3/test1{6,7,8}.py
deleting: work3/test16.py
deleting: work3/test17.py
deleting: work3/test18.py
[root@test-centos7 ~]# unzip -l /tmp/test1.zip
Archive:  /tmp/test1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      457  11-17-2015 06:02   work3/test1.py
     3261  11-17-2015 06:02   work3/test10.py
     1567  11-17-2015 06:02   work3/test11.py
      694  11-18-2015 05:06   work3/test13.py
      347  11-17-2015 06:02   work3/test15.py
      904  11-17-2015 06:02   work3/test19.py
---------                     -------
     7230                     6 files

 

9.指定したファイル・ディレクトリのみを解凍する

zipファイルの中から、意図したファイルやディレクトリのみを解凍する場合は、unzipコマンドで引数としてファイルPATHを指定してあげればいい。
なお、ディレクトリの場合は再帰的に解凍出来ないので、ワイルドカード付きで指定する必要がある。

unzip 対象となるzipファイルのPATH 解凍するファイル・ディレクトリPATH

20151118_000008

[root@test-centos7 ~]# unzip -l /tmp/test1.zip
Archive:  /tmp/test1.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      457  11-17-2015 06:02   work3/test1.py
     3261  11-17-2015 06:02   work3/test10.py
     1567  11-17-2015 06:02   work3/test11.py
      694  11-18-2015 05:06   work3/test13.py
      347  11-17-2015 06:02   work3/test15.py
      904  11-17-2015 06:02   work3/test19.py
       67  11-17-2015 05:01   work/TEST1.sh
      141  11-17-2015 05:04   work/TEST2.sh
      150  11-17-2015 05:14   work/TEST3.sh
       75  11-17-2015 05:18   work/TEST4.sh
       67  11-17-2015 05:17   work/TESTr.sh
---------                     -------
     7730                     11 files
[root@test-centos7 ~]# unzip /tmp/test1.zip work3/test10.py
Archive:  /tmp/test1.zip
  inflating: work3/test10.py
[root@test-centos7 ~]# unzip /tmp/test1.zip work/*
Archive:  /tmp/test1.zip
  inflating: work/TEST1.sh
  inflating: work/TEST2.sh
  inflating: work/TEST3.sh
  inflating: work/TEST4.sh
  inflating: work/TESTr.sh

 

10.高圧縮率 or 高速圧縮にする

zipコマンドでは、(そんなに変わらないけど)オプションによって圧縮率を変動させることが出来る。

  • -0 … 無圧縮(ただまとめただけ)
  • -1 … 圧縮率は低いが高速
  • -9 … 圧縮率は高いが低速

20151118_000009

[root@test-centos7 ~]# ls -ls /work3/test1*.py | awk '{sum = sum + $6} END {print sum}'
15067
[root@test-centos7 ~]# zip -0 /tmp/test-0.zip /work/test1*.py
  adding: work/test1.py (stored 0%)
  adding: work/test10.py (stored 0%)
  adding: work/test11.py (stored 0%)
  adding: work/test12.py (stored 0%)
  adding: work/test13.py (stored 0%)
  adding: work/test14.py (stored 0%)
  adding: work/test15.py (stored 0%)
  adding: work/test16.py (stored 0%)
  adding: work/test17.py (stored 0%)
  adding: work/test18.py (stored 0%)
  adding: work/test19.py (stored 0%)
[root@test-centos7 ~]# zip -1 /tmp/test-1.zip /work/test1*.py
  adding: work/test1.py (deflated 51%)
  adding: work/test10.py (deflated 69%)
  adding: work/test11.py (deflated 57%)
  adding: work/test12.py (deflated 68%)
  adding: work/test13.py (deflated 57%)
  adding: work/test14.py (deflated 44%)
  adding: work/test15.py (deflated 35%)
  adding: work/test16.py (deflated 28%)
  adding: work/test17.py (deflated 64%)
  adding: work/test18.py (deflated 43%)
  adding: work/test19.py (deflated 55%)
[root@test-centos7 ~]# zip -9 /tmp/test-9.zip /work/test1*.py
  adding: work/test1.py (deflated 51%)
  adding: work/test10.py (deflated 73%)
  adding: work/test11.py (deflated 59%)
  adding: work/test12.py (deflated 71%)
  adding: work/test13.py (deflated 60%)
  adding: work/test14.py (deflated 45%)
  adding: work/test15.py (deflated 35%)
  adding: work/test16.py (deflated 29%)
  adding: work/test17.py (deflated 66%)
  adding: work/test18.py (deflated 43%)
  adding: work/test19.py (deflated 57%)
[root@test-centos7 ~]# ls -la /tmp/test-*
-rw-r--r--. 1 root root 16773 11月 18 05:49 /tmp/test-0.zip
-rw-r--r--. 1 root root  7547 11月 18 05:49 /tmp/test-1.zip
-rw-r--r--. 1 root root  7117 11月 18 05:49 /tmp/test-9.zip

 

上の例を見るとわかるように、それぞれのオプションによってzipファイルの容量が異なっている。
無圧縮においてはむしろ容量が増えているような状態だ。

基本的には、時間を掛けたくない場合は「-1」を、そんなに圧縮率は変わらないが、ある程度容量を抑えたい場合は「-9」を付与すればよいだろう。

 

11.zipファイルの解凍テストを行う

ファイルの解凍を実際に行わず、動作テストのみを行う場合はunzipコマンドで「-t」オプションを付与する。

unzip -t 対象となるzipファイルのPATH

20151118_000010

[root@test-centos7 ~]# unzip -t /tmp/test1.zip
Archive:  /tmp/test1.zip
    testing: work3/test1.py           OK
    testing: work3/test10.py          OK
    testing: work3/test11.py          OK
    testing: work3/test13.py          OK
    testing: work3/test15.py          OK
    testing: work3/test19.py          OK
    testing: work/TEST1.sh            OK
    testing: work/TEST2.sh            OK
    testing: work/TEST3.sh            OK
    testing: work/TEST4.sh            OK
    testing: work/TESTr.sh            OK
No errors detected in compressed data of /tmp/test1.zip.
[root@test-centos7 ~]# ls -la work{,3}/
ls: work/ にアクセスできません: そのようなファイルやディレクトリはありません
ls: work3/ にアクセスできません: そのようなファイルやディレクトリはありません

 

詳解 圧縮処理プログラミング C言語で実装する圧縮処理アルゴリズム 詳解 圧縮処理プログラミング C言語で実装する圧縮処理アルゴリズム

シェルでグルーピングを利用してリダイレクトを一発で行う

$
0
0

リダイレクトで、複数のコマンドの実行結果を同じファイルに書き出したいとき、1コマンドに対し1リダイレクトの処理を書くと結構面倒くさい。
そんなときは、グルーピング({}で実行するコマンドを囲む)してリダイレクトを行うと良いだろう。

20151116_000015

 

[root@test-centos7 ~]# { echo "aaaaaa";
> echo "bbbbb";
> echo "ccccc"; } > /tmp/test1234.txt
[root@test-centos7 ~]#
[root@test-centos7 ~]# cat /tmp/test1234.txt
aaaaaa
bbbbb
ccccc

コンソールから実行する場合は「;(セミコロン)」が各コマンドの末尾に必要になるが、これはシェルスクリプトで書く場合は不要。

UNIXシェルスクリプト マスターピース132 UNIXシェルスクリプト マスターピース132

nc(Ncat)コマンドで覚えておきたい使い方3個(ncコマンドCentOS 7版)

$
0
0

前回も紹介したLinuxでポートの疎通確認を行う際によく用いるncコマンド。
実はこのコマンド、netcatではなくCentOS 7の場合だとnampプロジェクトのncatに置き換えられているのだ。

今後はncもこのncatコマンドに置き換えられている事になるので、このコマンドの使い方についても(あんま変わらんけど)紹介することにした。
なお、検証に使用したコマンドはCentOS 7に入れている”Ncat: Version 6.40 ( http://nmap.org/ncat )”とする。

20151116_000000

[root@test-centos7 ~]# nc --version
Ncat: Version 6.40 ( http://nmap.org/ncat )

 

コマンドが置き換わったため、netcatでは使えていたオプションが無かったりする。
例えば「-z」オプションなんて無いので、レンジ指定で空きポートを確認する手法は使うことが出来ないので注意が必要だ。

なお、前回紹介した手法のうち、以下についてはnetcatコマンドと変わらないため、割愛する。
変わった(できなくなった)のは、ポート範囲を指定してのスキャンだけだ。

  • 1.基本的な使い方・クライアントとして動作させる
  • 2.基本的な使い方・サーバとして動作させる
  • 3.ファイルを転送する
  • 4.IPv4、IPv6を指定する
  • 5.通信の詳細を取得する
  • 6.ソースアドレス・ポートを指定する
  • 8.ポートへのアクセス時にコマンド(bash等)が実行されるようにする

 

1.通信にsslを利用する

ncatの場合、「–ssl」を付与することで通信にSSLを使用することができる。
デフォルトではSHA1で通信が行われる。

nc -vl ポート番号 --ssl # サーバ側
nc -v 対象ホスト(IPアドレス等) ポート番号 --ssl

20151116_000010

SSLで通信を行わせる場合は、サーバ・クライアントともに「–ssl」オプションを付与する必要がある点に注意。
SSLを利用できるということで、その他のオプション(鍵ファイルを指定したり等)も付与する事が出来る。

2.SCTPで通信を行う

あまり使うシチュエーションは思いつかないが、「–sctp」を付与することで、SCTPプロトコルでの通信を行う事も出来る。

20151116_000012

 

3.送信・受信専用にする

オプションとして「–send-only」を付与することで送信専用に、「–recv-only」を付与することで受信専用として動作させることができる。
例えば、右側のコンソールをクライアントとして送信専用にすると、左のコンソールで入力した内容は受信されない。

20151116_000014

 

その他、細かいオプション(同時接続数の制限や接続許可ホストの指定、コマンドの実行方法など)もあるが基本的にはnetcatとそう変わらない。

CentOS7システム管理ガイドsystemd/NetworkManager/Firewalld徹底攻略 CentOS7システム管理ガイドsystemd/NetworkManager/Firewalld徹底攻略

シェルスクリプトで『getopts』を使ってオプションの処理を行わせる

$
0
0

仕事などでシェルスクリプトを作っていると、引数としてオプションを付与させるようなスクリプトを作りたくなる事がある。
そういったオプション関係の処理を簡単に行えるのが、今回紹介する『getopts』コマンドだ。仕事でスクリプトを組んでいれば、一度は利用するだろう。

このコマンドを利用することで、オプションを付与させるタイプのシェルスクリプトを簡単に作成することが可能になる。
基本的には、以下の例のようにwhile、caseと組み合わせる使い方がセオリーだ。

●example.sh

#!/bin/sh

############################################
# この例では、以下のオプションを付与させる #
# -a … オプション                         #
# -b … 文字列を後に付与するオプション     #
# -c … オプション                         #
############################################

# FLAG_A … 「-a」オプションが認識されているかどうか
# ARGS_B … 「-b」オプションで付与した文字列を格納
# FLAG_C … 「-c」オプションが認識されているかどうか
FLAG_A=0
ARGS_B=""
FLAG_C=0

# whileでgetoptsを用いる
# getoptsに引数として、使用するオプションの文字列を渡している。
# 文字列を後に付与するオプションの場合、「文字:」といった書き方をする。
while getopts "ab:c" op
do
    case $op in
        a)
          FLAG_A=1
          ;;
        b)
          # オプションに対する引数は「$OPTARG」で取得できる
          ARGS_B="$OPTARG"
          ;;
        c)
          FLAG_C=1
          ;;
        *)
          exit 1
          ;;
    esac
done

echo "指定されたオプションであれば「1」もしくは付与した文字列が表示される"
echo "-a: " $FLAG_A
echo "-b: " ${ARGS_B:="指定されませんでした"}
echo "-c: " $FLAG_C

それでは、実際に上のスクリプトを実行してみよう。

20151118_000017

[root@test-centos7 ~]# sh /work/example.sh
指定されたオプションであれば「1」もしくは付与した文字列が表示される
-a:  0
-b:  オプションが付与されませんでした
-c:  0
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/example.sh -b 'aaaaa' -c
指定されたオプションであれば「1」もしくは付与した文字列が表示される
-a:  0
-b:  aaaaa
-c:  1
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/example.sh -b -c
指定されたオプションであれば「1」もしくは付与した文字列が表示される
-a:  0
-b:  -c
-c:  0
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/example.sh -b
/work/example.sh: オプションには引数が必要です -- b
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/example.sh -d
/work/example.sh: 不正なオプションです -- d

順番通りにオプションを書かなくても正常に認識されるし、不正なオプションの場合はその旨を表示してくれている。

UNIXシェルスクリプト マスターピース132 UNIXシェルスクリプト マスターピース132

tarコマンド(GNU拡張版)で覚えておきたい使い方13個

$
0
0

Linux、UNIXでアーカイブファイルに関するコマンドといえば、やはりtarコマンドだろう。
アーカイブファイルとは、多数のファイルをそのユーザ・グループ情報やパーミッション、タイムスタンプ等の情報と共に、一つにまとめたファイルのことだ。ただのアーカイブファイルだと圧縮までは行われないため、通常はgzipと組み合わせて圧縮もさせる。

今回はこのtarを作成するtarコマンドについて、覚えておくと便利な使い方を紹介する。
なお、使用したのはCentOS 7にインストールされている以下のバージョンとなる。

20151125_000013

[root@test-centos7 ~]# tar --version
tar (GNU tar) 1.26
Copyright (C) 2011 Free Software Foundation, Inc.
使用許諾 GPLv3+: GNU GPL version 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

[参考訳]
これはフリーソフトウェアです. 変更と再配布は自由です.
法律で認められる範囲で「無保証」です.

作者: John Gilmore, Jay Fenlason.

 

1.アーカイブファイルの作成

アーカイブファイルを作成する場合は、通常だと以下のようにコマンドを実行する。
なお、アーカイブに含める対象としてディレクトリを指定すると再帰的に含めてくれる。

tar cvf 作成するアーカイブファイル アーカイブに含めるファイルPATH ...

 

指定しているオプション「cvf」それぞれの意味は以下。

  • c … アーカイブファイルを作成する
  • v … 詳細の表示
  • f … 作成するアーカイブファイル名を指定

 

gzipによる圧縮も同時に行う場合は、「z」オプションを付与する。
基本的には、こちらで覚えておけば問題ない。

tar czvf 作成するアーカイブファイル アーカイブに含めるファイルPATH ...

 

bz2による圧縮を行う場合は、「j」オプションを付与する。

tar cjvf 作成するアーカイブファイル アーカイブに含めるファイルPATH ...

20151125_000003

[root@test-centos7 ~]# tar cvf /tmp/tar_test.tar /work/test12.*
tar: メンバ名から先頭の `/' を取り除きます
/work/test12.py
/work/test12.py.old
/work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar czvf /tmp/tar_test.tar.gz /work/test12.*
tar: メンバ名から先頭の `/' を取り除きます
/work/test12.py
/work/test12.py.old
/work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar cjvf /tmp/tar_test.tar.bz2 /work/test12.*
tar: メンバ名から先頭の `/' を取り除きます
/work/test12.py
/work/test12.py.old
/work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# ls -la /tmp/tar_test.*
-rw-r--r--. 1 root root 20480 11月 25 08:20 /tmp/tar_test.tar
-rw-r--r--. 1 root root  2107 11月 25 08:21 /tmp/tar_test.tar.bz2
-rw-r--r--. 1 root root  1838 11月 25 08:20 /tmp/tar_test.tar.gz
[root@test-centos7 ~]#
[root@test-centos7 ~]# file /tmp/tar_test.*
/tmp/tar_test.tar:     POSIX tar archive (GNU)
/tmp/tar_test.tar.bz2: bzip2 compressed data, block size = 900k
/tmp/tar_test.tar.gz:  gzip compressed data, from Unix, last modified: Wed Nov 25 08:20:54 2015

 

2.アーカイブファイルの展開

アーカイブファイルを展開する場合は、以下のようにコマンドを実行する。
なお、展開したファイルはカレントディレクトリ配下に展開される。

tar xvf 展開するアーカイブファイルPATH

20151125_000004

[root@test-centos7 ~]# ls -la /tmp/tar_test.*
-rw-r--r--. 1 root root 20480 11月 25 08:20 /tmp/tar_test.tar
-rw-r--r--. 1 root root  2107 11月 25 08:21 /tmp/tar_test.tar.bz2
-rw-r--r--. 1 root root  1838 11月 25 08:20 /tmp/tar_test.tar.gz
[root@test-centos7 ~]#
[root@test-centos7 ~]# file /tmp/tar_test.*
/tmp/tar_test.tar:     POSIX tar archive (GNU)
/tmp/tar_test.tar.bz2: bzip2 compressed data, block size = 900k
/tmp/tar_test.tar.gz:  gzip compressed data, from Unix, last modified: Wed Nov 25 08:20:54 2015
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar xvf /tmp/tar_test.tar
work/test12.py
work/test12.py.old
work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar xvf /tmp/tar_test.tar.gz
work/test12.py
work/test12.py.old
work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar xvf /tmp/tar_test.tar.bz2
work/test12.py
work/test12.py.old
work/test12.sh

 

3.アーカイブファイルの展開先ディレクトリを指定する

アーカイブファイル展開時に、展開先のディレクトリを指定する場合は「-C」オプションにて指定することが出来る。

tar xvf 展開するアーカイブファイルPATH -C 展開先ディレクトリ

20151125_000008

[root@test-centos7 ~]# pwd
/root
[root@test-centos7 ~]# tar xvf /tmp/tar_test.tar.gz -C /work4
work/test12.py
work/test12.py.old
work/test12.sh
[root@test-centos7 ~]# ls -la /work4/
合計 4
drwxr-xr-x.  3 root root   17 11月 25 14:32 .
drwxr-xr-x. 33 root root 4096 11月 25 14:31 ..
drwxr-xr-x.  2 root root   58 11月 25 14:32 work
[root@test-centos7 ~]#
[root@test-centos7 ~]# ls -la $(find /work4/ -type f)
-rwxr-xr-x. 1 root root 4450 11月  3 07:36 /work4/work/test12.py
-rwxr-xr-x. 1 root root 4450 11月  3 07:36 /work4/work/test12.py.old
-rw-r--r--. 1 root root  573 10月 28 20:39 /work4/work/test12.sh

 

4.アーカイブファイルの中身をリスト表示する

アーカイブファイルの中身をリスト表示する場合は、「t」オプションを用いる。

tar tvf 中身を確認するアーカイブファイルPATH
tar tvf 中身を確認するアーカイブファイルPATH アーカイブファイル内の表示させたいファイルPATH # 特定のファイルのみ表示させたい場合

20151125_000007

[root@test-centos7 ~]# ls -la /tmp/tar_test.*
-rw-r--r--. 1 root root 20480 11月 25 08:20 /tmp/tar_test.tar
-rw-r--r--. 1 root root  2107 11月 25 08:21 /tmp/tar_test.tar.bz2
-rw-r--r--. 1 root root  1838 11月 25 08:20 /tmp/tar_test.tar.gz
[root@test-centos7 ~]#
[root@test-centos7 ~]# file /tmp/tar_test.*
/tmp/tar_test.tar:     POSIX tar archive (GNU)
/tmp/tar_test.tar.bz2: bzip2 compressed data, block size = 900k
/tmp/tar_test.tar.gz:  gzip compressed data, from Unix, last modified: Wed Nov 25 08:20:54 2015
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.bz2
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# # 特定のファイルのみを表示する場合(例:test12.pyのみ指定)
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py

 

5.アーカイブファイルから特定のファイルのみを展開させる

アーカイブファイルから、特定のファイルのみを展開させる場合は、以下のように引数として対象のファイルPATHを指定する。

tar xvf 展開するアーカイブファイルPATH 展開するファイル

20151125_000010

[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar xvf /tmp/tar_test.tar.gz work/test12.sh
work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# ls -la work/
合計 8
drwxr-xr-x.  2 root root   22 11月 25 14:37 .
dr-xr-x---. 23 root root 4096 11月 25 14:37 ..
-rw-r--r--.  1 root root  573 10月 28 20:39 test12.sh

6.アーカイブファイルにファイル・ディレクトリを追加する

既存のアーカイブファイルにファイルやディレクトリを追加する場合は、「r」オプションを付与する。

tar rvf 対象のアーカイブファイルPATH 追加するファイル・ディレクトリPATH

20151125_000011

[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar rvf /tmp/tar_test.tar.gz /work/test1*.sh
tar: メンバ名から先頭の `/' を取り除きます
/work/test10.sh
/work/test11.sh
/work/test12.sh
/work/test13.sh
/work/test14.sh
/work/test15.sh
/work/test16.sh
/work/test17.sh
/work/test18.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root        96 2015-10-14 09:00 work/test10.sh
-rw-r--r-- root/root      1168 2015-10-28 20:24 work/test11.sh
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root      1276 2015-10-28 20:49 work/test13.sh
-rw-r--r-- root/root     64363 2015-10-28 21:04 work/test14.sh
-rw-r--r-- root/root      4871 2015-10-28 21:19 work/test15.sh
-rw-r--r-- root/root       106 2015-10-28 21:48 work/test16.sh
-rw-r--r-- root/root      3570 2015-10-28 22:09 work/test17.sh
-rw-r--r-- root/root        88 2015-11-15 08:56 work/test18.sh

 

7.アーカイブファイルからファイル・ディレクトリを削除する

既存のアーカイブファイルからファイルやディレクトリを削除する場合は、「–delete」オプションを用いる。

tar vf 対象のアーカイブファイルPATH --delete 削除するファイル

20151125_000012

[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py
-rwxr-xr-x root/root      4450 2015-11-03 07:36 work/test12.py.old
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root        96 2015-10-14 09:00 work/test10.sh
-rw-r--r-- root/root      1168 2015-10-28 20:24 work/test11.sh
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root      1276 2015-10-28 20:49 work/test13.sh
-rw-r--r-- root/root     64363 2015-10-28 21:04 work/test14.sh
-rw-r--r-- root/root      4871 2015-10-28 21:19 work/test15.sh
-rw-r--r-- root/root       106 2015-10-28 21:48 work/test16.sh
-rw-r--r-- root/root      3570 2015-10-28 22:09 work/test17.sh
-rw-r--r-- root/root        88 2015-11-15 08:56 work/test18.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar vf /tmp/tar_test.tar.gz --delete work/*.py*
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root        96 2015-10-14 09:00 work/test10.sh
-rw-r--r-- root/root      1168 2015-10-28 20:24 work/test11.sh
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root      1276 2015-10-28 20:49 work/test13.sh
-rw-r--r-- root/root     64363 2015-10-28 21:04 work/test14.sh
-rw-r--r-- root/root      4871 2015-10-28 21:19 work/test15.sh
-rw-r--r-- root/root       106 2015-10-28 21:48 work/test16.sh
-rw-r--r-- root/root      3570 2015-10-28 22:09 work/test17.sh
-rw-r--r-- root/root        88 2015-11-15 08:56 work/test18.sh

 

8.アーカイブファイル作成時に特定のファイルを除外する

アーカイブファイルを作成する際、ディレクトリを指定して再帰的に指定するが、特定のサブディレクトリだけは含めないようにしたい事があるだろう。
そんなときは、「-–exclude」オプションもしくは「-X」オプションを使用すると良いだろう。

tar cvf 作成するアーカイブファイルPATH --exclude 除外ディレクトリのPATH アーカイブ対象ディレクトリ # 除外対象をコマンドで指定する場合
tar cvf 作成するアーカイブファイルPATH -X 除外ディレクトリのPATHを書いたファイル アーカイブ対象ディレクトリ # 除外対象をファイルに記述する場合

20151112_000003

[root@test-centos7 ~]# find /work8 -type d
/work8
/work8/work8-1
/work8/work8-1/8-1-2
/work8/work8-1/8-1-3
/work8/work8-1/8-1-4
/work8/work8-2
/work8/work8-2/8-2-4
/work8/work8-2/8-2-2
/work8/work8-3
/work8/work8-4
/work8/work8-4/8-4-2
/work8/work8-4/8-4-1
/work8/work8-4/8-4-7
/work8/work8-5
/work8/work8-6
[root@test-centos7 ~]# tar czvf /tmp/test8.tar.gz --exclude /work8/work8-1 /work8
tar: メンバ名から先頭の `/' を取り除きます
/work8/
/work8/work8-2/
/work8/work8-2/8-2-4/
/work8/work8-2/8-2-2/
/work8/work8-3/
/work8/work8-4/
/work8/work8-4/8-4-2/
/work8/work8-4/8-4-1/
/work8/work8-4/8-4-7/
/work8/work8-5/
/work8/work8-6/

 

9.アーカイブファイル内のPATHで、ワイルドカードやパターンを指定する

アーカイブファイル内のファイルやディレクトリを指定する際、色々な指定方法を使う事が出来る。

  • –anchored … ファイル名の先頭とパターンが一致
  • –ignore-case … 大文字小文字を無視
  • –no-anchored … 任意の ‘/’ 以降にパターンが一致(標準で除外)
  • –no-ignore-case … 大文字小文字を考慮して一致 (標準)
  • –no-wildcards … 逐語的文字列一致
  • –no-wildcards-match-slash … ワイルドカードが ‘/’に一致しない
  • –wildcards … use wildcards (default)
  • –wildcards-match-slash … ワイルドカードが ‘/’ に一致(標準で除外)

基本的にはワイルドカード(*)が有効になっているので、それで指定すると良いだろう。

 

10.アーカイブファイルと実際のファイルの差異を確認する

アーカイブファイルと実際のファイルの差異(といっても、ファイルサイズや最終更新日での比較だが)を確認する場合、「d」オプションを付与すると良いだろう。
そのまま実行するとカレントディレクトリ配下のファイルと比較するので、「-C」で比較先のディレクトリを指定すると良い。

tar dvf 比較するアーカイブファイル -C 比較先ディレクトリ

20151125_000014

[root@test-centos7 ~]# pwd
/root
[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root        96 2015-10-14 09:00 work/test10.sh
-rw-r--r-- root/root      1168 2015-10-28 20:24 work/test11.sh
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root      1276 2015-10-28 20:49 work/test13.sh
-rw-r--r-- root/root     64363 2015-10-28 21:04 work/test14.sh
-rw-r--r-- root/root      4871 2015-10-28 21:19 work/test15.sh
-rw-r--r-- root/root       106 2015-10-28 21:48 work/test16.sh
-rw-r--r-- root/root      3570 2015-10-28 22:09 work/test17.sh
-rw-r--r-- root/root        88 2015-11-15 08:56 work/test18.sh
[root@test-centos7 ~]# ls -la /work/test1*.sh
-rw-r--r--. 1 root root    96 10月 14 09:00 /work/test10.sh
-rw-r--r--. 1 root root  1174 11月 25 18:40 /work/test11.sh
-rw-r--r--. 1 root root   573 10月 28 20:39 /work/test12.sh
-rw-r--r--. 1 root root  1276 10月 28 20:49 /work/test13.sh
-rw-r--r--. 1 root root 64363 10月 28 21:04 /work/test14.sh
-rw-r--r--. 1 root root  4871 10月 28 21:19 /work/test15.sh
-rw-r--r--. 1 root root   106 10月 28 21:48 /work/test16.sh
-rw-r--r--. 1 root root  3570 10月 28 22:09 /work/test17.sh
-rw-r--r--. 1 root root    88 11月 15 08:56 /work/test18.sh
[root@test-centos7 ~]# tar dvf /tmp/tar_test.tar.gz -C /
work/test12.sh
work/test10.sh
work/test11.sh
work/test11.sh: 最終修正時刻が異なります
work/test11.sh: サイズが異なります
work/test12.sh
work/test13.sh
work/test14.sh
work/test15.sh
work/test16.sh
work/test17.sh
work/test18.sh

 

11.アーカイブファイル内のファイルの中身を参照する

アーカイブファイル内のファイルを参照する場合は、「O」オプションを用いる。
中のファイルを指定しないとアーカイブファイル全体を参照してしまうので、必要に応じて中身を指定する。

tar xOf 対象のアーカイブファイル [参照するアーカイブファイル内のファイル]

20151125_000015

[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root        96 2015-10-14 09:00 work/test10.sh
-rw-r--r-- root/root      1168 2015-10-28 20:24 work/test11.sh
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root      1276 2015-10-28 20:49 work/test13.sh
-rw-r--r-- root/root     64363 2015-10-28 21:04 work/test14.sh
-rw-r--r-- root/root      4871 2015-10-28 21:19 work/test15.sh
-rw-r--r-- root/root       106 2015-10-28 21:48 work/test16.sh
-rw-r--r-- root/root      3570 2015-10-28 22:09 work/test17.sh
-rw-r--r-- root/root        88 2015-11-15 08:56 work/test18.sh
[root@test-centos7 ~]# tar xOf /tmp/tar_test.tar.gz work/test18.sh
get_date=`date +%d -d '1 day'`
if [ $get_date = "01" ];then
    echo "月末です"
fi

 

これを使うことで、アーカイブファイルの中身(ログファイルなど)に対しgrepを行う事も出来る。

20151125_000016

 

12.展開したファイルを別のコマンドに引き渡す

展開したファイルを別のコマンドで処理する場合、「–to-command=」オプションを使う。
なお、コマンドに引き渡した場合はファイルの展開は行われないので注意する。

tar xvf 展開するアーカイブファイル --to-command=コマンド

引き渡すコマンド内で使用できる主な変数は以下。

  • $TAR_MODE … アーカイブファイル内のパーミッション
  • $TAR_FILENAME … アーカイブファイル内のファイル名
  • $TAR_UNAME … アーカイブファイル内のファイルのオーナー名
  • $TAR_UID … アーカイブファイル内のファイルのオーナーID
  • $TAR_GNAME … アーカイブファイル内のファイルのグループ名
  • $TAR_GID … アーカイブファイル内のファイルのグループID
  • $TAR_SIZE … アーカイブファイル内のファイルサイズ

 

例えば、アーカイブファイルから展開するファイルPATHを取得して、オリジナルファイルをlsで見る場合だと、以下のようにコマンドを実行する。

20151125_000017

[root@test-centos7 ~]# tar tvf /tmp/tar_test.tar.gz
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root        96 2015-10-14 09:00 work/test10.sh
-rw-r--r-- root/root      1168 2015-10-28 20:24 work/test11.sh
-rw-r--r-- root/root       573 2015-10-28 20:39 work/test12.sh
-rw-r--r-- root/root      1276 2015-10-28 20:49 work/test13.sh
-rw-r--r-- root/root     64363 2015-10-28 21:04 work/test14.sh
-rw-r--r-- root/root      4871 2015-10-28 21:19 work/test15.sh
-rw-r--r-- root/root       106 2015-10-28 21:48 work/test16.sh
-rw-r--r-- root/root      3570 2015-10-28 22:09 work/test17.sh
-rw-r--r-- root/root        88 2015-11-15 08:56 work/test18.sh
[root@test-centos7 ~]#
[root@test-centos7 ~]# tar xvf /tmp/tar_test.tar.gz --to-command='ls -la /$TAR_FILENAME'
work/test12.sh
-rw-r--r--. 1 root root 573 10月 28 20:39 /work/test12.sh
work/test10.sh
-rw-r--r--. 1 root root 96 10月 14 09:00 /work/test10.sh
work/test11.sh
-rw-r--r--. 1 root root 1174 11月 25 18:40 /work/test11.sh
work/test12.sh
-rw-r--r--. 1 root root 573 10月 28 20:39 /work/test12.sh
work/test13.sh
-rw-r--r--. 1 root root 1276 10月 28 20:49 /work/test13.sh
work/test14.sh
-rw-r--r--. 1 root root 64363 10月 28 21:04 /work/test14.sh
work/test15.sh
-rw-r--r--. 1 root root 4871 10月 28 21:19 /work/test15.sh
work/test16.sh
-rw-r--r--. 1 root root 106 10月 28 21:48 /work/test16.sh
work/test17.sh
-rw-r--r--. 1 root root 3570 10月 28 22:09 /work/test17.sh
work/test18.sh
-rw-r--r--. 1 root root 88 11月 15 08:56 /work/test18.sh

 

13.sshコマンドと組み合わせる

sshコマンドと組み合わせる事で、ローカルのファイルをアーカイブした状態でscp転送したり、その逆も行う事ができる。
詳細についてはリンク先で記述しているので、そちらを参照してもらいたい。

#【ローカル→リモート】ローカルでファイル・フォルダを圧縮し、リモートでアーカイブファイルとして保持させる
tar zcvf - /アーカイブ化したいディレクトリのパス | ssh ユーザ名@リモートホスト "cat &gt; /リモート側で作成するアーカイブ・ファイルのパス

#【ローカル→リモート】ローカルのアーカイブファイルをリモートで解凍する
ssh ユーザ名@リモートホスト "tar zxvf -C リモート側で展開させたいフォルダ -" &lt; /リモート側で解凍させたいアーカイブファイルのパス #【リモート→ローカル】リモートでファイル・フォルダを圧縮し、ローカルでアーカイブファイルとして保持させる ssh ユーザ名@リモートホスト "tar -cf - /アーカイブ化したいディレクトリのパス" | gzip &gt; /ローカル側で作成するアーカイブ・ファイルのパス

#【リモート→ローカル】リモートのアーカイブファイルをローカルで解凍する
ssh ユーザ名@リモートホスト "cat /ローカル側で解凍させたいアーカイブファイル" | tar zxvf - -C ローカル側で展開させたいフォルダ

 

以上、この他にも使い方は色々あると思うが、最低限この辺を覚えておけばそんなに困らないであろう。

初心者のためのGNUオクターブ入門: コマンドとグラフィックスの分かりやすい説明 初心者のためのGNUオクターブ入門: コマンドとグラフィックスの分かりやすい説明

シェルスクリプトで指定した月の第何何曜日を取得する

$
0
0

いい感じで家でお酒飲んでて、ゴミ出しの日を意識してふと思い立ち、指定した日の第何何曜日(第3水曜とか、第4金曜とか…)をbashで取得出来ないかなと思ったのでやってみた。
ncalとかあると一行で取得出来そうだったけど、手元のCentOS 7だと入ってなかったのでそれを使わずに出来ないか調べた。

で、dateコマンドのみでで上手く出せれば良かったんだけど、少し目論見が外れてしまった。
「-d」で月初日と次の曜日を同時に指定できればよかったんだけど…

20151127_000000

[root@test-centos7 ~]# date
2015年 11月 27日 金曜日 00:20:52 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '1 monday'
2015年 11月 30日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '2 monday'
2015年 12月  7日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '2015/11/01 1 monday'
2015年 11月  1日 日曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '1 monday 2015/11/01'
2015年 11月  1日 日曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# date -d '2015/11/01' -d '1 monday'
2015年 11月 30日 月曜日 00:00:00 JST

とまぁ、こんな感じで思ったようには動かなかった。
なお、dateコマンドをネストしても動きは変わらずなので、dateコマンドのみでは上手くいかなそうだ。残念。

ううん、phpならstrtotimeで一発なんだけどなぁ…同じように指定すればいいかと思ったけど、そう甘くはない。
pythonにもこの辺の関数は無いっぽい…

【参考:2015年12月の第2月曜日をphpで取得する】

php -r 'echo date("Y/m/d\n", strtotime("Second Monday of Dec 2015"));'
[root@test-centos7 ~]# php -r 'echo date("Y/m/d\n", strtotime("Second Monday of Dec 2015"));'
2015/12/14

しょうがないので、大分出来が悪いけどやっつけでシェルスクリプトを組んでみることにした。
(使うことがあるのか不明だが)

●get_weekday_of_month.sh

base="$1/01"
base_dayofweek=$( date -d $base +%w )
# 0=Sun,1=Mon,2=Tue,3=Wed,4=Thu,5=Fri,6=Sat
target_dayofweek=$2
week_no=$3

if [ $base_dayofweek="0" ]; then
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 + 7*($week_no-1))) days"
else
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 - 1 + 7*($week_no-1))) days"
fi

20151127_000001

[root@test-centos7 ~]# cat /work/get_weekday_of_month.sh
base="$1/01"
base_dayofweek=$( date -d $base +%w )
# 0=Sun,1=Mon,2=Tue,3=Wed,4=Thu,5=Fri,6=Sat
target_dayofweek=$2
week_no=$3

if [ $base_dayofweek="0" ]; then
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 + 7*($week_no-1))) days"
else
    date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 - 1 + 7*($week_no-1))) days"
fi
#date -d "$base + $(( (7 - base_dayofweek + target_dayofweek) % 7 )) days"

[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/get_weekday_of_month.sh 2015/12 1 2
2015年 12月 14日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/get_weekday_of_month.sh 2015/10 1 2
2015年 10月 12日 月曜日 00:00:00 JST
[root@test-centos7 ~]#
[root@test-centos7 ~]# sh /work/get_weekday_of_month.sh 2015/10 3 2
2015年 10月 14日 水曜日 00:00:00 JST

 

…そもそも、書いてて思ったんだけどスクリプトでその辺の日程を取得する意味があったんだろうか?
使う事あるのだろうか?ゴミの日くらいしか思いつかない…

 

シェルプログラミング実用テクニック (Software Design plus) シェルプログラミング実用テクニック (Software Design plus)

dateutilsを使って簡単に指定月の第何何曜日を取得する

$
0
0

先ほど、指定月の第何何曜日を取得するスクリプトを作成したのだが、もうちょっといいツールが無いか探して見たところ、dateutilsというものを見つけた。
これのdateconvを使えば、かなり簡単に指定曜日の日付を取得出来そうだ。

1.インストール

インストールは、RHEL系だとコンパイルが必要のようだ。
以下のコマンドを実行する。

wget https://bitbucket.org/hroptatyr/dateutils/downloads/dateutils-0.3.4.tar.xz
tar xvf dateutils-0.3.4.tar.xz
cd dateutils-0.3.4
./configure
make
make install

 

Ubuntuの場合、apt-getでインストールできる。

sudo apt-get install dateutils

これでインストールが完了する。

2.コマンドの実行

さて、それでは早速コマンドを実行してみよう。
以下のように実行する事で、指定した月の第何何曜日を取得できる。

dateconv YYYY-MM-何週目か-曜日 -i "%Y-%m-%c-%a" -f '%Y/%m/%d'

20151127_000002

[root@test-centos7 ~]# dateconv 2015-01-03-Mon -i "%Y-%m-%c-%a" -f '%Y/%m/%d'
2015/01/19
[root@test-centos7 ~]# cal 01 2015
      1月 2015
日 月 火 水 木 金 土
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

[root@test-centos7 ~]#
[root@test-centos7 ~]# dateconv 2015-11-03-Mon -i "%Y-%m-%c-%a" -f '%Y/%m/%d'
2015/11/16
[root@test-centos7 ~]# cal 11 2015
      11月 2015
日 月 火 水 木 金 土
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

 

お~、こりゃ楽だわ。
他にも色々なツールがあるみたいだし、うまく使いこなせれば何かできるかも。。。

JP1によるジョブ管理の実践ノウハウ 第2版 JP1によるジョブ管理の実践ノウハウ 第2版

cronで第何何曜日にスクリプトを実行するか指定する

$
0
0

シェルスクリプトで第何何曜日を取得する方法について調べてたので、今度はcronで、毎月決まった週の曜日にだけスクリプトを実行させるような指定方法がないか調べてみることにした。
で、調べてみると、どうやら日の範囲と曜日はandではなくor指定になっているようで、以下のように指定すると「指定曜日もしくは指定範囲日の場合はコマンド実行」となってしまう。

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
# 第一月曜日の深夜3時にコマンドを実行させたい(が、この指定だと毎月1~7日もしくは月曜日にコマンドが実行される)
0 3 1-7 * 1 ユーザ コマンド

で、これを回避するには、以下のようにコマンド実行側で曜日を識別させることで『何週目の何曜日にスクリプトを実行させる』事は可能だ。

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
# * * 範囲を指定 * * ユーザ [ $(date "+\%w") -eq 曜日 ] && コマンド

# 第1月曜の深夜3時にコマンド実行
0 3 1-7 * * root [ $(date "+\%w") -eq 1 ] && コマンド

# 第2水曜の深夜3時に以下略
0 3 8-14 * * root [ $(date "+\%w") -eq 3 ] && コマンド

# 第3木曜の以下略
0 3 15-21 * * root [ $(date "+\%w") -eq 4 ] && コマンド

# 第4日曜の以下略
0 3 22-28 * * root [ $(date "+\%w") -eq 0 ] && コマンド

 

結局、指定範囲内には必ず第何曜日が来るわけなので、日付をその範囲で指定した上で曜日を指定してあげればいいだけなんだよね。
なお、曜日ではなく月末にコマンドを実行させたい場合は、以下のように『月末になりうる日』に当日が月末かどうかを判定させて、月末であればコマンドをキックさせるようにすればいい。

0 3 28-31 * * root [ $(date "+\%d" -d "+1day") -eq 1 ] && コマンド

 

とりあえず、これで第何何曜日にスクリプトが実行されるように指定することが出来る。

【参考】 http://blog.livedoor.jp/blackwingcat/archives/1029569.html

 

2週間でできる! スクリプト言語の作り方 (Software Design plus) 2週間でできる! スクリプト言語の作り方 (Software Design plus)

dateコマンドで現在時刻を騙す『libfaketime』

$
0
0

dateコマンドでは、「-d」で○○日後とか、□月後といった指定で日付を取得することが出来る。
しかし、特定の日付を指定した上で○○日後の日付を指定する事が出来ない。

もしdateコマンドで特定の日付の○○日後、次の○曜日といった指定をする場合、今回紹介する『libfaketime』を用いると便利だろう。
これは、dateコマンドが読み込む現在日時を変数「FAKETIME」とすることで、システム時刻に変更を加える事なく特定の日付をdateコマンドで出力させることが出来る。

1.インストール

まずはインストール。
以下コマンドを実行し、コンパイル・インストールを行う。

git clone https://github.com/wolfcw/libfaketime
cd libfaketime/
make
make install

2.日時を出力させる

次に、実際にどう使うのかについて記述する。
以下のように、インストールしたライブラリ「libfaketime.so.1」をLD_PRELOADに代入し、dateコマンド実行と同時に変数「FAKETIME」に特定の日時を入れるだけだ。

export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1
FAKETIME='特定の日時' date

20151130_000000

[root@test-centos7 libfaketime]# date
2015年 11月 30日 月曜日 22:15:44 JST
[root@test-centos7 libfaketime]#
[root@test-centos7 libfaketime]# date -d 'next sunday'
2015年 12月  6日 日曜日 00:00:00 JST
[root@test-centos7 libfaketime]#
[root@test-centos7 libfaketime]# export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1
[root@test-centos7 libfaketime]# FAKETIME='2015-01-01 00:00:00' date
2015年  1月  1日 木曜日 00:00:00 JST
[root@test-centos7 libfaketime]#
[root@test-centos7 libfaketime]# FAKETIME='2015-01-01 00:00:00' date -d 'next sunday'
2015年  1月  4日 日曜日 00:00:00 JST

 

まぁ、あまり使うことはないような気もするけれどどこかで役に立ちそうな気がしなくもない。

Linuxだからできること200(日経BPパソコンベストムック) Linuxだからできること200(日経BPパソコンベストムック)

Microsoft Azureで仮想マシンの起動ログを取得する

$
0
0

先日、Azure上のLinuxサーバがssh接続できず、そもそもOSが上がっているのかどうなのかわからない、という事があった。
AWSしかり、Azureしかり、こういったクラウドサービスの場合だと仮想マシンのコンソールに接続できず、こういった事が発生すると非常に困る事になる。
で、こういったOSが起動しているのかどうかもわからない状態の場合、基本的にはOSの起動ログを取得して起動していないのか、起動中なのか切り分けを行ったり、もし起動していない場合は対象の仮想マシンのHDDイメージを取得して手元で仮想マシン作って確認したり…といった対応が必要になってくるようだ(後はサポートかな?)。

AWSではもともと起動ログの取得方法が用意されていたのだが、Azureの場合は新しいポータル画面(2015年12月現在)で接続しないと取得設定出来ないみたいなので、念のため備忘として残しておく。
といっても特に難しいものではない。まずは新しいポータル画面(https://portal.azure.com/)にアクセスし、左メニューから仮想マシン(クラシック)を選択する。

20151201_000000

 

で、お目当ての仮想マシンを選択して「設定」>「ブート診断」>「設定」で、以下のように状態を「オン」、ストレージアカウントを選択して「ブート診断」にチェックを入れて保存するだけだ。

20151201_000001

 

保存すると診断情報の更新が行われるので、これが完了以降、ブート時のログを閲覧できるようになる。
地味にコンソールのスクリーンショットを取得することも出来るようだ。

20151201_000002

 

というか正直な所、AWSもAzureもシリアルコンソール操作を出来るようにしてくれりゃいいんだけど…
技術的には可能な気もするのだけど、なんでダメなんだろ?負荷が高くなりすぎるのかな?

別の仮想マシンとシリアル接続をさせるようにして、そいつをコンソールサーバとして使えるようになればいいのになぁ
OS側の設定変更しないとだったり、Windowsの場合だと操作内容が限られるけど。

ひと目でわかるAzure 基本から学ぶサーバー&ネットワーク構築 ひと目でわかるAzure 基本から学ぶサーバー&ネットワーク構築

bashのsetコマンドで覚えておきたい使い方9個

$
0
0

シェルスクリプトを作る上で、以外と便利なのがsetコマンド。
オプションごとに関連性が薄いので覚えにくいのだが、使いこなせれば結構役に立つ事が多いコマンドだ。

今回は、そんなsetコマンドで覚えておきたい使い方についてを紹介する。

1.引数・オプションなしで実行(変数の一覧を表示する)

setコマンドは、引数無しで実行すると現在設定されている変数の一覧を表示させることが出来る。

set

20151201_000003

[root@test-centos7 ~]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="45" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.45(1)-release'
COLUMNS=112
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/root
HOSTNAME=test-centos7
HOSTTYPE=x86_64
ID=0
IFS=$' \t\n'
LANG=ja_JP.UTF-8
LESSOPEN='||/usr/bin/lesspipe.sh %s'
LINES=36
LOGNAME=root
LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:'
MACHTYPE=x86_64-redhat-linux-gnu
MAIL=/var/spool/mail/root
MAILCHECK=60
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin:/root/bin
PIPESTATUS=([0]="0")
PPID=23637
PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
PS1='[\u@\h \W]\$ '
PS2='> '
PS4='+ '
PWD=/root
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=1
SSH_CLIENT='XXX.XXX.XXX.XXX 52074 22'
SSH_CONNECTION='XXX.XXX.XXX.XXX 52074 YYY.YYY.YYY.YYY 22'
SSH_TTY=/dev/pts/0
TERM=xterm
UID=0
USER=root
XDG_RUNTIME_DIR=/run/user/0
XDG_SESSION_ID=8459
_=PATH
colors=/root/.dircolors
[root@test-centos7 ~]#
[root@test-centos7 ~]# set | grep TEST
[root@test-centos7 ~]# TEST=1234
[root@test-centos7 ~]# set | grep TEST
TEST=1234

 

2.実行するコマンドをコンソール上に出力する

「set -v」で実行するコマンドを、「set -x」でそのコマンドの変数等を展開した状態でコンソール上に表示させることが出来る。
(以下例の「printf ~」というのはPS1の表示を行っているもの)

20151201_000005

[root@test-centos7 ~]# echo $HOME
/root
[root@test-centos7 ~]#
[root@test-centos7 ~]# set -v
printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
[root@test-centos7 ~]# echo $HOME
echo $HOME
/root
printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
[root@test-centos7 ~]# set +v
set +v
[root@test-centos7 ~]#
[root@test-centos7 ~]# set -x
++ printf '\033]0;%s@%s:%s\007' root test-centos7 '~'
[root@test-centos7 ~]# echo $HOME
+ echo /root
/root
++ printf '\033]0;%s@%s:%s\007' root test-centos7 '~'
[root@test-centos7 ~]# set +x
+ set +x

 

ちなみに、無効にする際はオプション値を「+」を使って記述してあげると良い。

 

3.シェルスクリプトの構文チェックだけを行わせる

シェルスクリプト内に「set -n」もしくは「set -o noexec」を記述することで、スクリプト実行時に構文チェックだけ行わせて、その中の処理を実行させないようにすることが出来る。
例えば、以下のように「set -n」を記述していないスクリプトを実行するとコマンドが実行されてしまうが、記述しているスクリプトだと構文チェックだけを行ってくれている。

20151201_000004

[root@test-centos7 ~]# ls /tmp/test
[root@test-centos7 ~]# cat /work/test27.sh
#!/bin/bash
#set -n
mkdir "/tmp/test/test1234"
for fichier in `ls`
do
    if [[ -f "$fichier ]]; then
          echo "$fichier"
    fi
done
[root@test-centos7 ~]# cat /work/test28.sh
#!/bin/bash
set -n
mkdir "/tmp/test/test5678"
for fichier in `ls`
do
    if [[ -f "$fichier ]]; then
          echo "$fichier"
    fi
done
[root@test-centos7 ~]# bash /work/test27.sh
/work/test27.sh: 行 7: 一致する `"' を探索中に予期しないファイル終了 (EOF) です
/work/test27.sh: 行 10: 条件単項演算子に予期しない引数です
/work/test27.sh: 行 10: 構文エラー: 予期しないファイル終了 (EOF) です
[root@test-centos7 ~]# bash /work/test28.sh
/work/test28.sh: 行 7: 一致する `"' を探索中に予期しないファイル終了 (EOF) です
/work/test28.sh: 行 10: 条件単項演算子に予期しない引数です
/work/test28.sh: 行 10: 構文エラー: 予期しないファイル終了 (EOF) です
[root@test-centos7 ~]# ls /tmp/test
test1234

4.シェルスクリプト内で実行された処理が正常終了しない場合、処理を停止させる

シェルスクリプト内で「set -e」もしくは「set -o errexit」と記述することで、一部の処理を除いて、スクリプト内の実行コマンドが正常終了しなかった場合にスクリプトを即終了させる事が出来る。
例えば、以下の例の場合だと「set -e」が無いとエラーになった後の処理も実行されてしまうが、「set -e」が記述されていればそこで処理が止まっている。

20151202_000000

[root@test-centos7 ~]# ls -la /tmp/TEST
ls: /tmp/TEST にアクセスできません: そのようなファイルやディレクトリはありません
[root@test-centos7 ~]# cat /work/test29.sh
#!/bin/bash
#set -e
mkdir /tmp/TEST1234/TEST
mkdir /tmp/TEST1234/TEST/1234
mkdir /tmp/TEST1234/TEST/5678
[root@test-centos7 ~]# cat /work/test30.sh
#!/bin/bash
set -e
mkdir /tmp/TEST1234/TEST
mkdir /tmp/TEST1234/TEST/1234
mkdir /tmp/TEST1234/TEST/5678
[root@test-centos7 ~]#
[root@test-centos7 ~]# bash /work/test29.sh
mkdir: ディレクトリ `/tmp/TEST1234/TEST' を作成できません: そのようなファイルやディレクトリはありません
mkdir: ディレクトリ `/tmp/TEST1234/TEST/1234' を作成できません: そのようなファイルやディレクトリはありません
mkdir: ディレクトリ `/tmp/TEST1234/TEST/5678' を作成できません: そのようなファイルやディレクトリはありません
[root@test-centos7 ~]# bash /work/test30.sh
mkdir: ディレクトリ `/tmp/TEST1234/TEST' を作成できません: そのようなファイルやディレクトリはありません

 

ただ、先ほども記述したように一部の処理(ループ内の処理だったり、三項演算子内だったりetc)については、正常終了でなくてもそのままスクリプトは実行されてしまうので注意が必要。

 

5.パス名の展開を無効にする

「set -f」もしくは「set -o noglob」を実行すると、シェルで「*(アスタリスク)」などでのワイルドカードでの展開を無効にする事ができる。

20151202_000001

[root@test-centos7 ~]# ls /tmp/*
/tmp/*           /tmp/date_file   /tmp/tar_test.tar      /tmp/tar_test.tar.gz
/tmp/aaaaaa.log  /tmp/dddddd.log  /tmp/tar_test.tar.bz2  /tmp/test1

/tmp/test:
test1234

/tmp/test12345678:

/tmp/test2:
[root@test-centos7 ~]#
[root@test-centos7 ~]# set -f
[root@test-centos7 ~]# ls /tmp/*
/tmp/*
[root@test-centos7 ~]# set +f
[root@test-centos7 ~]# ls /tmp/*
/tmp/*           /tmp/date_file   /tmp/tar_test.tar      /tmp/tar_test.tar.gz
/tmp/aaaaaa.log  /tmp/dddddd.log  /tmp/tar_test.tar.bz2  /tmp/test1

/tmp/test:
test1234

/tmp/test12345678:

/tmp/test2:

 

6.ブレース展開を無効にする

「set +B」もしくは「set +o braceexpand」で、シェルのブレース展開を無効にする事ができる。

20151202_000002

[root@test-centos7 ~]# echo abc{123,456,789}def
abc123def abc456def abc789def
[root@test-centos7 ~]#
[root@test-centos7 ~]# set +B
[root@test-centos7 ~]# echo abc{123,456,789}def
abc{123,456,789}def

 

7.リダイレクト時の上書きを無効にする

「set -C」および「set -o noclobber」を実行すると、リダイレクト時のファイルへの上書き(追記はできる)を無効にすることが出来る。
(ただし、「>|」を用いると上書き可能になっている)

20151202_000005

[root@test-centos7 ~]# echo 0 > /tmp/aaaaa
[root@test-centos7 ~]# cat /tmp/aaaaa
0
[root@test-centos7 ~]#
[root@test-centos7 ~]# echo 01 > /tmp/aaaaa
[root@test-centos7 ~]# cat /tmp/aaaaa
01
[root@test-centos7 ~]#
[root@test-centos7 ~]# set -C
[root@test-centos7 ~]#
[root@test-centos7 ~]# echo 0123 > /tmp/aaaaa
-bash: /tmp/aaaaa: 存在するファイルを上書きできません
[root@test-centos7 ~]# echo 0123 >> /tmp/aaaaa
[root@test-centos7 ~]# cat /tmp/aaaaa
01
0123
[root@test-centos7 ~]#
[root@test-centos7 ~]# echo 0123 >| /tmp/aaaaa
[root@test-centos7 ~]# cat /tmp/aaaaa
0123

 

8.引数を指定し直す

setコマンドにオプション無しで引数を渡すと、スクリプトの引数を設定し直す事が出来る。

20151202_000006

[root@test-centos7 ~]# set 1234 5678
[root@test-centos7 ~]# echo $2
5678
[root@test-centos7 ~]# echo $1
1234
[root@test-centos7 ~]#
[root@test-centos7 ~]# cat /work/test31.sh
#!/bin/bash
set abcdef ghijk 12345
echo $1
echo $3
echo $2
[root@test-centos7 ~]#
[root@test-centos7 ~]# bash /work/test31.sh
abcdef
12345
ghijk
[root@test-centos7 ~]# bash -x /work/test31.sh
+ set abcdef ghijk 12345
+ echo abcdef
abcdef
+ echo 12345
12345
+ echo ghijk
ghijk

 

9.現在のオプション状態を確認する

setコマンドで設定したオプション値を確認する場合、ただ「set -o」と実行することでその一覧を確認出来る。

20151202_000007

[root@test-centos7 ~]# set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       on
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off

 

プロフェショナル・シェルプログラミング (アスキー書籍) プロフェショナル・シェルプログラミング (アスキー書籍)

pexpectのターミナルサイズを変更する

$
0
0

pythonのpexpectを使っていて、ターミナルのサイズがおかしくなっていることに気づいたのでその備忘。
どうやらpexpcetでは、指定が無いとターミナルのサイズを「24,80」にしてしまうようだ(迷惑な…)。

スクリーンショット 2015-12-02 18.04.18.png

 

で、これだとちょっと困るので、以下の例のようにcursesで現在のターミナルサイズを取得させて、pexpectのsetwinsizeでターミナルウィンドウのサイズを修正させることにした。

#! /usr/bin/python
# -*- coding: utf-8 -*-
import pexpect
import os
import curses

# ターミナルサイズを取得
curses.setupterm()
term_lines = int(curses.tigetnum("lines"))
term_cols = int(curses.tigetnum("cols"))
print term_lines,term_cols

# pexpectを実行
foo = pexpect.spawn('bash')
foo.setwinsize(term_lines,term_cols)

# pexpectのターミナルサイズを取得
foo.expect(['$','#'])
foo.sendline('stty size')

foo.interact()

スクリーンショット 2015-12-02 18.40.24.png

n-mbp2011:~ XXXXX$ stty size
30 109
n-mbp2011:~ XXXXX$
n-mbp2011:~ XXXXX$ cat script/test.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
import pexpect
import os
import curses

# ターミナルサイズを取得
curses.setupterm()
term_lines = int(curses.tigetnum("lines"))
term_cols  = int(curses.tigetnum("cols"))
print term_lines,term_cols

# pexpectを実行
foo = pexpect.spawn('bash')
foo.setwinsize(term_lines,term_cols)

# pexpectのターミナルサイズを取得
foo.expect(['$','#'])
foo.sendline('stty size')

foo.interact()
n-mbp2011:~ XXXXX$ python script/test.py
30 109
bash-3.2$ stty size
30 109
bash-3.2$

 

とりあえずこれでターミナルサイズは修正できた。

ハイパフォーマンスPython ハイパフォーマンスPython
Viewing all 1028 articles
Browse latest View live