[解決済み] Bashのevalコマンドとその典型的な使用法
質問
bashのmanページを読んだ後、これに関して ポスト .
が具体的にどのようなものなのか、まだ理解できないでいます。
eval
コマンドは何をするもので、どのような使い方が一般的でしょうか。例えば、次のような場合です。
bash$ set -- one two three # sets $1 $2 $3
bash$ echo $1
one
bash$ n=1
bash$ echo ${$n} ## First attempt to echo $1 using brackets fails
bash: ${$n}: bad substitution
bash$ echo $($n) ## Second attempt to echo $1 using parentheses fails
bash: 1: command not found
bash$ eval echo \${$n} ## Third attempt to echo $1 using 'eval' succeeds
one
また、ドル記号とバックスラッシュはどのようにこの問題に関係しているのでしょうか?
どのように解決するのか?
eval
は引数として文字列を受け取り、あたかもコマンドラインでその文字列を入力したかのように評価します。(複数の引数を渡した場合は、最初にスペースをはさんで結合されます)。
${$n}
はbashの構文エラーです。中括弧の中には、変数名と、いくつかの可能な接頭辞と接尾辞があるだけで、任意のbash構文を持つことはできず、特に変数展開は使用できない。この変数に名前がある変数の値」という言い方はあるのですが。
echo ${!n}
one
$(…)
は、括弧の中で指定されたコマンドをサブシェル(つまり、現在のシェルから変数値などのすべての設定を継承する別のプロセス)で実行し、その出力を収集します。つまり
echo $($n)
実行
$n
をシェルコマンドとして実行し、その出力を表示します。このため
$n
と評価されます。
1
,
$($n)
は、コマンドを実行しようとします。
1
は存在しない。
eval echo \${$n}
に渡されたパラメータを実行します。
eval
. 展開後、パラメータは
echo
と
${1}
. そこで
eval echo \${$n}
はコマンドを実行します。
echo ${1}
.
ほとんどの場合、変数の置換とコマンドの置換には二重引用符を使用しなければならないことに注意してください。
$
):
"$foo", "$(foo)"
.
変数やコマンドの置換は常に二重引用符で囲みます。
但し、削除する必要があることが分かっている場合は、この限りではありません。二重引用符がないと、シェルはフィールド分割を行い (つまり、変数の値やコマンドからの出力を別々の単語に分割する)、それぞれの単語をワイルドカードパターンとして扱います。たとえば
$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *
eval
はあまり使われません。いくつかのシェルでは、実行時まで名前がわからない変数の値を取得するのが最も一般的な使用方法です。bashの場合は
${!VAR}
構文があります。
eval
は、演算子や予約語などを含む長いコマンドを作成する必要がある場合にも便利です。
関連
-
deepin20を使って、ドローイングボードで画像を開くには?deepinのお絵かき掲示板で画像を開く2つの方法
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み] Bashでコマンドの出力に変数を設定するにはどうすればよいですか?
-
[解決済み] フォルダとそのサブフォルダ/ファイルのパーミッションを一括で変更する方法
-
[解決済み] Bashで標準出力と標準エラーの両方をファイルにリダイレクトして追記する方法
-
[解決済み] シェルコマンドの実行と出力のキャプチャ
-
[解決済み] Bashコマンドからテキストファイルの内部を検索・置換する
-
[解決済み] 特定のコマンドを無視するBashのエラー
-
[解決済み】Bashでファイル名と拡張子を抽出する。
-
[解決済み】bashで1つのコマンドでシェル変数にデフォルト値を割り当てる。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
deepin linuxでroot権限に切り替えるには?Deepinでrootに切り替えるためのヒント
-
Kali Linuxのマウスを左利き用に設定する方法は?Linuxマウス左利き操作選択方法
-
deepin20を使って、ドローイングボードで画像を開くには?deepinのお絵かき掲示板で画像を開く2つの方法
-
リクエスト・エンティティが大きすぎる問題の解決策
-
[解決済み] mkdirのオプションが明確でない
-
[解決済み] Linuxで特定のテキストを含むすべてのファイルを検索するにはどうすればよいですか?
-
[解決済み] ワイルドカードマッチングに基づいて、現在のフォルダとサブフォルダ内のすべてのファイルを再帰的に検索するにはどうすればよいですか?
-
[解決済み] Linux で grep を使ってファイル名だけを表示するにはどうしたらいいですか?
-
[解決済み] ターミナルで現在の日付と時刻を取得し、それに対してターミナルでカスタムコマンドを設定するにはどうすればよいですか?[クローズド]です。
-
[解決済み] Bashを使用して変数用のファイルを参照する方法は?