web-dev-qa-db-ja.com

start-stop-daemonで引用された引数が誤って解釈される

Start-stop-daemonを使用してinitスクリプトを作成しようとしています。私はデーモンへの議論に固執しています。これらをスクリプトの上部にある変数に保持したいのですが、引用符を取得して正しくフィルタリングすることができません。

ここではlsを使用するので、ほとんどの人が知らない、または気にしないバイナリや引数を調べる必要はありません。

私が探している最終結果は、start-stop ...を実行することですls -la "/ folder with space /"

DAEMON=/usr/bin/ls 
DAEMON_OPTS='-la "/folder with space/"'

start-stop-daemon --start --make-pidfile --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS

オプションをダブルエスケープし、無数の引用のバリエーションを試しても役に立たない...そして、それらはデーモンに到達し、常にめちゃくちゃになります。引用符で$ DAEMON_OPTSを囲むと状況が変わります...引用符以降は1つとして表示されます...しかし、正しい数ではありません:)

コマンドライン(start-stop ...)をエコーすると、画面に正確に適切なものが出力されます。しかし、デーモン(lsではなく実際のデーモン)は、引数の数が間違っていると文句を言います。

変数内の引用符がデーモンに正しく表示されるように変数を指定するにはどうすればよいですか?

21
Martin Westin

作業中のinitスクリプトで使用されている最終的な引用を投稿すると思いました。

COMMAND="/path/to/script -opt param param2 param3"
DAEMON_OPTS=" 0.0.0.0:$PORT -dest $OUTPUT_DIRECTORY -command"

start-stop-daemon --start --background --make-pidfile --pidfile $PID --exec $DAEMON -- $DAEMON_OPTS "\"$COMMAND\""

明らかに不完全で機能しない例ですが、その要点を理解していただければ幸いです。内側のペアがエスケープされた二重引用符は、トリックをしたものです。

9
Martin Westin

試してみてください

DAEMON_OPTS="-la '/folder with space/'"
start-stop-daemon --start ... -- $DAEMON_OPTS

何が起こるかというと、DAEMON_OPTSの外側の引用符は削除されますが、内側の引用符(単一引用符)は残ります。したがって、次の行は次のようになります。

start-stop-daemon --start ... -- -la '/folder with space/'

それはあなたが望むものです。

エスケープで同じ効果を達成することも可能ですが、これには多くのエスケープが必要です。最初に、割り当て中に引用符を保護し、その後、開始行が解析されて変数が展開されたときに、多分もう一度です。 :) bash -xはそのようなことのあなたの友達です。

[編集]上記のコードは、Linux以外のBourneおよびKorn Shellで動作します。 Linuxの場合、kshまたはbashを使用すると、シェルは全体を混乱させる追加の引用符を追加します。

FOLDER="/folder with space/"
DAEMON_OPTS="-la $FOLDER"
start-stop-daemon --start ... -- $DAEMON_OPTS

-xで実行すると、次のように表示されます。

FOLDER='/folder with space/'
DAEMON_OPTS='-la ~/folder with space/'
ls -la '~/folder' with space/

したがって、最初のWordのみが保護されます(おそらく、特殊な文字が含まれているためです)。 $FOLDERの前後に一重引用符を追加すると、次のようになります。

FOLDER='/folder with space/'
DAEMON_OPTS='-la '\''~/folder with space/'\'''
ls -la ''\''~/folder' with 'space/'\'''

よくやった。回避策:オプションを2つの変数に分割します。1つはオプションを使用し、もう1つはパスを使用します。

start-stop-daemon --start ... -- $DAEMON_OPTS "$DAEMON_PATH"

[EDIT2]これも機能します:

FOLDER="$HOME/folder with space/"
opt[0]=-la
opt[1]=$FOLDER
ls "${opt[@]}"

つまり、単語を配列に入れます。

15
Aaron Digulla

スペースを含むbash変数がある場合は常に、参照するときに引用符を使用してください。

start-stop-daemon --start --make-pidfile --pidfile $ PID --exec $ DAEMON-"$ DAEMON_OPTS"

1
snarshad

あなたはそれを引用符で逆にやってみましたか?このような:

 DAEMON_OPTS = '-la "/ folder with space /"'

よくわかりませんが、うまくいくかもしれません。

(私がそうするのに十分な評判を持っていれば、私は前の答えへのコメントとしてこれを投稿したでしょう)。

0
Enfors