後で使用するコマンドを変数に保存したい(コマンドの出力ではなく、コマンド自体)
次のような簡単なスクリプトがあります。
command="ls";
echo "Command: $command"; #Output is: Command: ls
b=`$command`;
echo $b; #Output is: public_html REV test... (command worked successfully)
ただし、もう少し複雑なことをしようとすると失敗します。たとえば、私が作る場合
command="ls | grep -c '^'";
出力は次のとおりです。
Command: ls | grep -c '^'
ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
ls: cannot access '^': No such file or directory
後で使用するために、このようなコマンド(パイプ/複数のコマンド)を変数に保存する方法はありますか?
Evalを使用します。
x="ls | wc"
eval "$x"
y=$(eval "$x")
echo "$y"
Donotuse eval
!任意のコードの実行を引き起こす大きなリスクがあります。
配列に入れて、二重引用符"${arr[@]}"
ですべての単語を展開してnotIFS
で単語を分割to 単語分割 。
cmdArgs=()
cmdArgs=('date' '+%H:%M:%S')
内部の配列の内容を確認します。 declare -p
を使用すると、内部の配列の内容を、各コマンドパラメーターを個別のインデックスで確認できます。そのような引数の1つにスペースが含まれている場合、配列への追加中に引用符で囲むと、Word分割による分割が防止されます。
declare -p cmdArgs
declare -a cmdArgs='([0]="date" [1]="+%H:%M:%S")'
コマンドを次のように実行します
"${cmdArgs[@]}"
23:15:18
(または)bash
関数を使用してコマンドを実行し、
cmd() {
date '+%H:%M:%S'
}
そして、関数を単に
cmd
POSIX sh
には配列がないため、最も近い方法は、位置パラメーターの要素のリストを作成することです。 POSIX sh
メールプログラムを実行する方法を次に示します
# POSIX sh
# Usage: sendto subject address [address ...]
sendto() {
subject=$1
shift
first=1
for addr; do
if [ "$first" = 1 ]; then set --; first=0; fi
set -- "$@" --recipient="$addr"
done
if [ "$first" = 1 ]; then
echo "usage: sendto subject address [address ...]"
return 1
fi
MailTool --subject="$subject" "$@"
}
このアプローチは、リダイレクトのない単純なコマンドしか処理できないことに注意してください。リダイレクト、パイプライン、for/whileループ、ifステートメントなどを処理できません。
var=$(echo "asdf")
echo $var
# => asdf
このメソッドを使用すると、コマンドがすぐに評価され、その戻り値が保存されます。
stored_date=$(date)
echo $stored_date
# => Thu Jan 15 10:57:16 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 10:57:16 EST 2015
バックティックと同じ
stored_date=`date`
echo $stored_date
# => Thu Jan 15 11:02:19 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 11:02:19 EST 2015
$(...)
でevalを使用しても、後で評価されることはありません。
stored_date=$(eval "date")
echo $stored_date
# => Thu Jan 15 11:05:30 EST 2015
# (wait a few seconds)
echo $stored_date
# => Thu Jan 15 11:05:30 EST 2015
evalを使用すると、eval
が使用されている場合に評価されます
stored_date="date" # < storing the command itself
echo $(eval "$stored_date")
# => Thu Jan 15 11:07:05 EST 2015
# (wait a few seconds)
echo $(eval "$stored_date")
# => Thu Jan 15 11:07:16 EST 2015
# ^^ Time changed
上記の例で、引数を指定してコマンドを実行する必要がある場合は、保存する文字列にそれらを入れます
stored_date="date -u"
# ...
Bashスクリプトの場合、これはめったに関連しませんが、最後の注意点です。 eval
に注意してください。制御する文字列のみを評価し、信頼できないユーザーからの文字列や信頼できないユーザーの入力から作成された文字列を評価しない.