2011-09-17 10 views
21

私のすべてのargsを含むbash変数を生成し、それらのargsにはスペースが含まれています。 これらの引数を使ってコマンドを起動すると - たとえば。 ls $ args - 引用符は正しく解釈されません。 ここでは、必要なファイルの作成と消去の例を示します。それとbash - 複数のargsを引用符で囲んでいる変数

#!/bin/bash 
f1="file n1" 
f2="file n2" 
# create files 
touch "$f1" "$f2" 
# concatenate arguments 
args="\"$f1\" \"$f2\"" 
# Print arguments, then launch 'ls' command 
echo "arguments :" $args 
ls $args 
# delete files 
rm "$f1" "$f2" 

、私は "ファイル、 N1" "ファイル N2" あなたはarray用を使用して検討するかもしれない

+0

http://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with -quotes-and-asterisk –

答えて

38

ためのいくつかの "そのようなファイルなし" のエラーを持っていませんargs、このようなもの:

args=("$f1" "$f2") 
ls "${args[@]}" 

(現時点で問題になっているのは、ファイル内とファイル名の間に違いはありません。)

+3

これは配列をサポートするBashのようなシェルでのみ動作します。下記の 'eval'はすべてのUnixシェルで動作します。 –

+0

@ arran-cudbard-bellまあ、本当ですが、質問は複数回 'bash'と言われるので、この解決策は最善の答えのように見えます。 – monnef

+1

私は構文が奇妙で不透明だと私には同意しません。 –

2

変数を位置パラメータとして設定するには、次のように入力します。 "$ @"や "$ 1"、 "$ 2"などで参照すると引用符は保持されます。変数名を二重引用符で囲んでください。

set -- "$f1" "$f2" 
touch "[email protected]" 
ls "[email protected]" 
rm "[email protected]" 
3

おそらく最悪の回答ですが、IFSを変更することができます。これは "内部フィールドセパレータ"であり、デフォルトでspace + tab + newlineと同じです。

#!/bin/sh 
IFS=, 
MAR="-n,my file" 
cat $MAR 

上記のスクリプトはcatを実行します。最初の引数は-n(番号付き行)になり、2番目の引数はmy fileになります。

26

evalを使用すると、展開と引用を評価してから、結果の文字列をシェルに入力したかのように実行します。

args="'$f1' '$f2'" 
eval ls $args 

のevalは、ls 'file n1' 'file n2'

を実行されるinitスクリプトでstart_stop_daemon/etc/default/から発信変数に引数を渡そうとし、非常によく似た問題を抱えていました。

+1

'eval'は深刻なセキュリティ上の問題があるため、ダウンホートされました。詳細についてはhttp://stackoverflow.com/a/37573041/120818を参照してください。基本的にはhttp://mywiki.wooledge。org/BashFAQ/048): "これは、あなたのコードが一度ではなく二度解析されるようにします;例えば、コードに変数参照がある場合、シェルのパーサはその変数の内容を評価します。あなたがそれを望むかどうかにかかわらず、シェルはそのコマンドを実行するかもしれません。 – HerbCSO

+3

Cのプログラミングでgotoを使うべきではないというのは、コードをラットのネストに変えるためにいくつかの開発者が使っているからです。 evalがセキュリティ問題を導入しないケースはたくさんありますが、これは有効な批判ではありません。 –

+2

私は@ ArranCudbard-Bellに同意します。変数引数を使用して潜在的に任意のコードを実行しています。 'eval'を使うと、コードはすでに状況よりも何かを行うことができません。 – siride

0

引用符で囲まれた引数を連結するためのレシピです。主にスクリプトを読みやすくするために使用されます。しかし、それは簡単にいくつかの引数をコメントアウトしても快適です。

PARAM1="a param with white spaces" 
PARAM2="some other funny param" 
PARAM3="third spaced param" 
#... 

PARAMS=$PARAM1 
PARAMS+='" "' 
PARAMS+=$PARAM2 
PARAMS+='" "' 
PARAMS+=$PARAM3 
#... 

eval command '"'$PARAMS'"' 
関連する問題