GNU/Linux >> Linux の 問題 >  >> Linux

コマンドをシェルスクリプトの変数に格納する方法は?

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 さん、コマンドの引用を思い出させてくれてありがとう!

Linux
  1. Linuxコマンドの出力を変数に割り当てる方法

  2. コマンドライン引数をシェルスクリプトに渡す方法は?

  3. シェルスクリプトで一時ファイルを作成するにはどうすればよいですか?

  1. Linuxコマンドのスクリプトを作成する方法

  2. 変数に格納されているコマンドを実行するにはどうすればよいですか?

  3. 実行されたシェルコマンドの結果をPythonの変数に保存する方法は?

  1. コマンドの出力をシェル変数に割り当てる方法は?

  2. コマンドの出力をシェル変数に保存しますか?

  3. 独自のIPアドレスを取得し、シェルスクリプトの変数に保存する方法は?