次のパラメーターを指定したrsyncコマンドがあります。
rsync -avz --{partial,stats,delete,exclude=".*"}
そのパラメーターを変数内に配置して、スクリプトで後で再利用したいと考えています。このようなもの:
#!/bin/bash
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
$VAR /dir1 /dir2
引用符、単一引用符、角かっこで試したが、成功しなかった。
次のパラメーターを指定したrsyncコマンドがあります。
rsync -avz --{partial,stats,delete,exclude=".*"}
そのパラメーターを変数内に配置して、スクリプトで後で再利用したいと考えています。このようなもの:
#!/bin/bash
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
$VAR /dir1 /dir2
引用符、単一引用符、角かっこで試したが、成功しなかった。
回答:
複雑なコマンドを変数に入れることは決して推奨されるアプローチではありません。BashFAQ / 050を参照してください-コマンドを変数に入れようとしていますが、複雑なケースは常に失敗します!
変数の代わりに関数を使用して引数を渡すことにした場合、要件は非常に単純になります。
何かのようなもの
rsync_custom() {
[ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
rsync -avz --{partial,stats,delete,exclude=".*"} "$@"
}
そして必要な引数を次のように渡します
rsync_custom /dir1 /dir2
関数の定義はある意味で非常に単純です。最初に、$#
ゼロであってはならない変数を使用して入力引数の数を確認します。引数が指定されていないというエラーメッセージをスローします。有効な引数がある場合"$@"
、関数に提供される実際の引数を表します。
これはあなたがまた、スクリプト/コマンドラインで、すなわちかなり頻繁に使用されるだろう機能である場合は、シェルのスタートアップ・ファイルに追加し.bashrc
、.bash_profile
インスタンスのために。
または、前述のように、読みやすくするために、中かっこを展開して引数を分離することは価値があります。
rsync_custom() {
[ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
rsync -avz --partial --stats --delete --exclude=".*" "$@"
}
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
これは、コマンドを実行しようと-avz
引数を持つ--partial
、--stats
など。ととVAR
のセットrsync
環境インチ
VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'
中かっこは引用符内で展開されておらず、代入内でも展開されておらず、変数が展開された後も展開されないため、引用フォームは機能しません。
コマンドライン引数を変数に格納する必要がある場合は、配列を使用します。
args=(rsync -avz --{partial,stats,delete,exclude=".*"})
今すぐ"${args[@]}"
に拡大するrsync
、-avz
、--partial
明確な言葉として、など。
配列を使用すると、必要に応じて条件に応じてリストにオプションを追加することもできます。たとえば、次のようにできます。
args=(this that)
if something ; then
args+=(another_arg)
fi
"$cmd" "${args[@]}"
少なくとも、オプションを部分的に変数に保存できます。
opts=$(echo --{ignore-case,word-regexp,count,exclude='"sys*.*"'})
マスキングは困難な場合があるため、テストは重要です。
echo $opts
--ignore-case --word-regexp --count --exclude="sys*"
grep $opts bytes *.log
履歴の使用、エイリアスの使用、関数の使用など、複数の選択肢があるため、私が考えることができる明らかなユースケースはありません。異なるプログラム間で共有する複雑なオプションはめったにありません。そのため、インタラクティブシェルのアドホックソリューションでは、エイリアスはより良い方法のように見えます。
alias cgrep='grep --ignore-case --word-regexp --count --exclude="sys*"'
cgrep bytes *.log
あなたのサンプル
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
割り当てが最初の空白で終了しているため、機能しません。ブランクをマスクする必要があります:
VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'
--deleteオプションを使用してテストするのはかなり危険ですよね。オプションには "、"と一重引用符を含めることができるため、マスキングはすぐに難しくなる可能性があります。私はエイリアスに行くか、歴史に依存します。
〜/ .bashrcファイルにエイリアスを保存して、複数のセッションで継続的に使用できます。関数はbashrcにも格納できますが、パラメーターを処理する場合は、関数に渡されてそこで評価されます。