eval を使用:
x="ls | wc"
eval "$x"
y=$(eval "$x")
echo "$y"
しない eval
を使用 !任意のコードが実行される大きなリスクがあります。
BashFAQ-50 - コマンドを変数に入れようとしていますが、複雑なケースは常に失敗します。
配列に入れて、すべての単語を二重引用符 "${arr[@]}"
で展開します しない IFS
にしましょう 単語分割により単語を分割します。
cmdArgs=()
cmdArgs=('date' '+%H:%M:%S')
内部の配列の内容を確認します。 declare -p
個々のインデックスで各コマンド パラメータを使用して内部の配列の内容を表示できます。そのような引数の 1 つにスペースが含まれている場合、配列に追加する際に内部を引用すると、単語分割による分割を防ぐことができます。
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 -- "[email protected]" --recipient="$addr"
done
if [ "$first" = 1 ]; then
echo "usage: sendto subject address [address ...]"
return 1
fi
MailTool --subject="$subject" "[email protected]"
}
このアプローチでは、リダイレクトのない単純なコマンドしか処理できないことに注意してください。リダイレクト、パイプライン、for/while ループ、if ステートメントなどを処理できません
もう 1 つの一般的な使用例は、curl
を実行する場合です。 複数のヘッダー フィールドとペイロードを使用します。以下のようにいつでも引数を定義して、 curl
を呼び出すことができます 展開された配列の内容
curlArgs=('-H' "keyheader: value" '-H' "2ndkeyheader: 2ndvalue")
curl "${curlArgs[@]}"
別の例
payload='{}'
hostURL='http://google.com'
authToken='someToken'
authHeader='Authorization:Bearer "'"$authToken"'"'
変数が定義されたので、配列を使用してコマンド引数を保存します
curlCMD=(-X POST "$hostURL" --data "$payload" -H "Content-Type:application/json" -H "$authHeader")
適切な引用展開を行います
curl "${curlCMD[@]}"
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 スクリプトの場合、これが関連することはめったにありませんが、最後に 1 つ注意してください。 eval
に注意 .あなたが制御する文字列のみを評価し、信頼されていないユーザーからの文字列や、信頼されていないユーザー入力から作成された文字列は決して評価しないでください。
- @CharlesDuffy さん、コマンドの引用を思い出させてくれてありがとう!