while read LINEでコマンドリストを実行させるシェル。
読込んだコマンドにパイプがついているとうまく動作しなかったけど、evalコマンドを使用することで、対処できる。
読込むファイル
1 2 3 |
[root@KVM test]# cat read.list cat /etc/hosts cat /etc/hosts | grep 127 |
失敗例その1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
[root@KVM test]# cat while.sh #!/bin/bash FILENAME=read.listcat ${FILENAME} | while read LINE do ${LINE} done [root@KVM test]# [root@KVM test]# sh -x while.sh + FILENAME=read.list + cat read.list + read LINE + cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 + read LINE + cat /etc/hosts '|' grep 127 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 cat: |: そのようなファイルやディレクトリはありません cat: grep: そのようなファイルやディレクトリはありません cat: 127: そのようなファイルやディレクトリはありません + read LINE [root@KVM test]# |
失敗例その2(${LINE}を””でくくってみる)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[root@KVM test]# cat while.sh #!/bin/bash FILENAME=read.listcat ${FILENAME} | while read LINE do "${LINE}" done [root@KVM test]# [root@KVM test]# sh -x while.sh + FILENAME=read.list + cat read.list + read LINE + 'cat /etc/hosts' while.sh: line 7: cat /etc/hosts: そのようなファイルやディレクトリはありません + read LINE + 'cat /etc/hosts | grep 127' while.sh: line 7: cat /etc/hosts | grep 127: そのようなファイルやディレクトリはありません + read LINE [root@KVM test]# |
成功例(“${LINE}”をevalコマンド経由で実行させる)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[root@KVM test]# cat while.sh #!/bin/bashFILENAME=read.listcat ${FILENAME} | while read LINE do eval “${LINE}” done [root@KVM test]# [root@KVM test]# sh -x while.sh + FILENAME=read.list + cat read.list + read LINE + eval ‘cat /etc/hosts’ ++ cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 + read LINE + eval ‘cat /etc/hosts | grep 127’ ++ cat /etc/hosts ++ grep 127 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 + read LINE [root@KVM test]# |
evalコマンドは変数を含んでいる変数を展開するコマンド。
その際、文字列等はそのまま展開されるので制御文字がいくら含まれていようと難しいエスケープ処理などは行わなくて良いみたい。
すごく便利だ。