web-dev-qa-db-ja.com

Bashで引用符付きの複数の引数を含む変数

私はすべての引数を含むbash変数を生成し、それらの引数にはスペースが含まれています。それらの引数を使用してコマンドを起動すると-たとえばls $ 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インチ

34
hibou

次のように、引数に array を使用することを検討できます。

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

(現在当たっている問題は、いったん補間が行われると、ファイル名内とファイル名間で違いがなくなることです。)

52
martin clayton

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

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

evalが実行されますls 'file n1' 'file n2'

非常によく似た問題があり、initスクリプトで/etc/default/からstart_stop_daemonにソースされた変数に引数を渡そうとしました。

33

setを使用して、変数を位置パラメータとして設定します。 "$@"または"$1""$2"などで参照すると、引用符が保持されます。変数名は必ず二重引用符で囲んでください。

set -- "$f1" "$f2"
touch "$@"
ls "$@"
rm "$@"
7
tripleee

これはおそらく最悪の答えですが、 [〜#〜] ifs [〜#〜] を変更できます。これは「内部フィールド区切り文字」であり、デフォルトではスペース+タブ+改行と同じです。

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

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

5
David Grayson

これが引用引数を連結するための私のレシピです-主にスクリプトを読みやすくするために使用されます。しかし、いくつかの議論を簡単にコメントアウトするのも快適です:

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'"'
0
bebbo