変数をbashスクリプトにパラメータとして渡し、bashスクリプトで評価する方法はありますか?
与えられた:
# cat /path/to/file/of/host/names
bob
tom
joe
etc...
# dofor
FILE=$1
shift
CMD=$*
while read host; do
# recursively turns "ssh \$host hostname" from $@ into:
# ssh bob hostname
# ssh tom hostname
# ssh joe hostname
# etc...
eval $CMD
done < $FILE
いつ:
# dofor /path/to/file/of/host/names "ssh \$host hostname"
それからssh host hostname
:/path/to/file/of/host/namesにリストされている各ホスト名に対して実行結果を受け取ります。たとえば、
bob.example.com
tom.example.com
joe.example.com
etc...
答え1
この試み:
#!/bin/bash
FILE=$1
shift
CMD=$*
cmds=""
source <({
cat $FILE | while read host; do
echo $CMD | sed -e "s|\$host|$host|g"
done
})
答え2
あなたはそれを使用することができます
#!/bin/bash
FILE=$1
exec 3<$FILE
while read -u 3 host; do
$2 $host $3
done
したがって、次のような場合:
$ cat /tmp/hostnames
some.host1.com
another.host2.net
some.host3.org
some.host4.com
その後、実行するとdofor.sh /tmp/hostnames ssh ls
順番に実行されます。
ssh some.host1.com ls
ssh another.host2.net ls
ssh some.host3.org ls
ssh some.host4.com ls
編集1:
より長いコマンド(またはその一部)を変更するには、引用符を使用ssh
してください。ls
dofor.sh /tmp/hostnames "ssh -p 23" "ls -lh /"
編集2:
次のスクリプトを使用すると、$host
コマンドの任意の場所で変数を使用できます。
#!/bin/bash
exec 3<$1
while read -u 3 host; do
eval $2
done
(私はこれを短縮しました - 役に立たない$FILE
変数は導入されませんでした。)ここで重要な部分はアポストロフィ$host 変数を含むコマンドの周辺:
dofor.sh /tmp/hostnames 'echo "trying $host :"; ssh -p 23 myuser@$host "ls -lh /"'
しかし、警戒する使用するのは危険ですeval
(参照l0b0の壁)ファイルの特定/tmp/hostnames
の行にコマンドが含まれている場合は、そのコマンドが実行されるためです。として使用しないことをお勧めしますroot
!
答え3
これはうまくいきますが、本物コンテンツを完全に制御できない場合は悪い考えです。$FILE
そしてこれには非常に簡単な文だけが含まれています。
while read -r
do
$REPLY
done < $FILE
SSHの例では、ホスト名を繰り返してより簡単な操作を実行できます。
while read -r host
do
echo -n "${host}:"
ssh "$host" hostname
done 9< "$FILE"
my hostname:remote hostname
アイテムのリストを返す必要があります。
実際のコマンドを含むファイルがある場合は、スペースが正しく処理されていることを確認する必要があります。それを処理する唯一の方法はどのパラメータ(たとえば、echo
複数のパラメータを持つコマンドを含む)はカスタム形式を使用します。比較的簡単な方法は、各コマンドと引数を␀文字で区切って、コマンドの最後の引数と次のコマンドの間に追加の␀文字を配置することです。