4

私は次のようなパラメータを受け入れるユーティリティ(ユニゾンですが、それは重要ではありません)を使用しています。

$ unison -path path1 -path path2 -path path3

次のように実行できるshスクリプトを作成したいと思います。

$ myscript path1 path2 path3

Posix準拠のソリューションを望んでいますが、bash固有のソリューションも適しています。

私はそれが次のようなものであるべきだと推測しています:

#!/bin/sh
unison ${*/ / -path }

しかし、これは機能しません。

編集:OK、私は何かを得たと思います:

#!/bin/bash
PARAMS=
for arg in "$@"
do
    PARAMS+=" -path '$arg'"
done
unison $PARAMS

問題は、これはbashでのみ機能することであり、パラメーターを引用するためのより良い方法があると確信しています。

4

5 に答える 5

5

チェックを外すと、次のように簡単になります。

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を使用すると、スペースを含む引数の処理が簡単になることに注意してください。ただし、質問はシェルについて尋ねます。

Bashでは、シェル配列変数を使用することも可能です。引数を配列に組み込み、その配列を引数としてunisonコマンドに渡します。

于 2009-06-08T14:53:36.853 に答える
4

Bashの配列を使用すると、引用の問題はすべて解消されます。

#!/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[@]}"
于 2009-06-09T17:51:28.257 に答える
3

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
于 2009-11-05T18:19:59.000 に答える
1

非常にbash固有のバージョンが必要な場合は、試すことができます

#!/ bin / sh

eval eval exec \
  unison -path \\ \\\" {$(eval echo \\\" \\\ $ {1 .. $#} \\\" | sed's / /、/ g')} \\\"

トリプルバックスラッシュで引用された文字をすべて削除すると、理解しやすくなりますが、説明して楽しみを損なうことはありません:-)

主な問題は、スペースを含むファイル名を処理することです。これは、トリプルバックラッシュの引用とダブル評価を説明しています。

于 2009-06-08T15:41:59.283 に答える
1

キャラクターを満足のいくように引用する方法は次のとおりです。

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
于 2014-09-12T20:01:26.007 に答える