質問
私はユーティリティを使用しています(ユニゾン, 、しかし、それはポイントではありません)次のようなパラメーターを受け入れます。
$ unison -path path1 -path path2 -path path3
このように実行できるSHスクリプトを書きたいと思います:
$ myscript path1 path2 path3
私はPOSIXに準拠したソリューションを望んでいますが、バッシュ固有のものも良いでしょう。
私はそれが次のようなものであるべきだと思います:
#!/bin/sh
unison ${*/ / -path }
しかし、これはうまくいきません。
編集: :わかりました、私は何かを手に入れたと思います:
#!/bin/bash
PARAMS=
for arg in "$@"
do
PARAMS+=" -path '$arg'"
done
unison $PARAMS
問題は、これがBashでのみ機能することであり、パラメーターを引用するより良い方法があると確信しています。
解決
チェックされていない、それは以下と同じくらい簡単かもしれません
exec unison -path $1 -path $2 -path $3
パス名にスペースが埋め込まれていない場合は、さまざまな数の引数を扱うことができます。
arglist=""
for path in "$@"
do
arglist="$arglist -path $path"
done
exec unison $arglist
パス名にスペースがある場合は、はるかに激しく作業する必要があります。私は通常、呼ばれるカスタムプログラムを使用します escape
, 、引用する必要がある議論を引用します eval
:
arglist=""
for path in "$@"
do
path=$(escape "$path")
arglist="$arglist -path $path"
done
eval exec unison "$arglist"
PerlまたはPythonを使用すると、スペースのスペースが簡単に処理されやすくなりますが、質問はShellについて尋ねます。
また、シェルアレイ変数を使用することはBashで実行可能である可能性があります - 引数を配列に組み込み、引数として配列を渡す unison
指図。
他のヒント
Bash's Arrayを使用すると、引用する問題はすべてなくなります。
#!/bin/bash
args=()
for i in "$@"; do
# With Bash >= 3:
args+=(-path "$i")
# +=() doesn't work in Bash 2
# args=("${args[@]}" -path "$i")
done
exec unison "${args[@]}"
Bashでは、使用できます "${@/#/-path }"
各位置パラメーターの開始を「-path」に置き換えます。文字列の使用を表すには %
それ以外の #
.
これが使用された単純なデモスクリプトです sed
そして繰り返し -e
オプション。 (もちろん、より効率的な使用方法があります sed
.)
#!/bin/bash
echo "Resulting arguments: ${@/#/-e }"
sed "${@/#/-e }"
そして、このように実行してください:
$ echo abc | demo s/a/A/ s/b/B/
我々が得る:
Resulting arguments: -e s/a/A/ -e s/b/B/
ABc
かなりのバッシュ固有のバージョンが必要な場合は、試すことができます
#! /bin/sh eval eval exec \ unison -path\\ \\\"{$(eval echo \\\"\\\${1..$#}\\\" | sed 's/ /,/g')}\\\"
すべてのトリプルバックスラッシュクォートのキャラクターを削除すると、これは理解しやすくなりますが、それを説明することで楽しみを台無しにしません:-)
主な合併症は、スペースのあるファイル名を処理することです。これは、トリプルバックラッシュの引用と二重評価を説明します。
キャラクターを満足して引用する方法は次のとおりです。
job_strategy()
{
local p
for p in "$@"; do
printf '-path\000%s\000' "$p"
done
}
job_process()
{
xargs -0 unison
}
job_strategy "path1" "path2" "path3" | job_process