while read LINEでコマンドリストを実行させるシェル。
読込んだコマンドにパイプがついているとうまく動作しなかったけど、evalコマンドを使用することで、対処できる。
読込むファイル
[root@KVM test]# cat read.list cat /etc/hosts cat /etc/hosts | grep 127
失敗例その1
[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}を””でくくってみる)
[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コマンド経由で実行させる)
[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コマンドは変数を含んでいる変数を展開するコマンド。
その際、文字列等はそのまま展開されるので制御文字がいくら含まれていようと難しいエスケープ処理などは行わなくて良いみたい。
すごく便利だ。
