grep
同じ(非常に長い)コマンドを複数回繰り返すスクリプトがあります。行の長さを短くしてスクリプトを読みやすくしたいので、命令の一部を変数に入れました。
次の行は次のとおりです(他のパラメータを使用してスクリプトで複数回繰り返されます)。
rsync -av --delete -R --exclude=alternatives /etc/ /backup.raw/ | grep -E '^deleting|[^/]$' >> /var/log/rsync.log
その行はうまくいきます。私はそれを次のように短縮してみました。
_rscmd='rsync -av --delete -R'
_mn=/backup.raw/
_grep='grep -E "^deleting|[^/]$"'
_rslog=/var/log/rsync.log
したがって、「最後の」行は次のようになります。
$_rscmd --exclude=alternatives /etc/ $_mn | $_grep >> $_rslog
しかし、その行は$_grep
変数で失敗します。どうすれば正しく書くことができますか?私は成功"…"
しませ'…'
んでした。 grepコマンドはもともと機能しました。
答え1
変数を使用している場合は、複数の部分(コマンドとパラメータ)に分割することは機能しません。この例の場合eval
:
eval $_rscmd --exclude=alternatives /etc/ $_mn | eval $_grep >> "$_rslog"
一般的に使用するのが最善です。シェル機能またはニックネーム 変数を使用するよりも:
alias my_grep='grep -E "^deleting|[^/]$"'
...
... | my_grep >> "$_rslog"
答え2
一般的なアプローチは、コマンドのパラメータを変数に設定することです。
_mn=/backup.raw/
_rscmdarg='-av --delete -R'
_greparg='-E "^deleting|[^/]$"'
_rslog=/var/log/rsync.log
$_rslog
ファイルやディレクトリと同じように$_mn
アーカイブしても大丈夫です。
「最後の」行は次のとおりです。
rsync $_rscmdarg --exclude=alternatives /etc/ $_mn | grep $_greparg >> $_rslog
答え3
他の2つの答えの最良の部分を統合する1つの方法(IMHO)は、変更せずに必要なすべての機能を含め、さまざまな状況で変化する機能を指定する引数を使用するシェル関数を作成することです。例:
my_rsync_grep() {
rsync -av --delete -R "$1" "$2" "$3" | grep -E '^deleting|[^/]$' >> /var/log/rsync.log
}
必須パラメータを使用して呼び出します。
my_rsync_grep --exclude=alternatives /etc/ /backup.raw/
rsync … | grep …
これはコマンドを別のスクリプトに入れたのと同じです。 (ただし、別々のファイルではないため、複数のファイルを追跡する構成管理の問題や他のスクリプトを呼び出す方法に関する論理的な問題(例:?を使用しますか?)がなく、関数を毎回./
呼び出すことはありません。追加のディスクI / Oは発生しません。)
メモ:
読みやすさとプログラミングスタイルの理由から、I / Oリダイレクト(
>> /var/log/rsync.log
)を関数から移動してすべての呼び出しに適用できます。my_rsync_grep --exclude=alternatives /etc/ /backup.raw/ >> /var/log/rsync.log
これにより、スクリプトを読んだり保守したりする人に、その行がファイルに書き込まれていることが明らかになります。しかし、スクリプトに誤って矛盾が発生しやすくなります。もちろん、ファイル名を変数(たとえば)に入れることで、1行を
$_rslog
減らすことができます/var/log/rsycn.log
。1行が長すぎて関数コードの読みやすさが低下したと思われる場合は、複数行に分けることができます。
\
最後の行を除くすべての行に1つを追加します。rsync -av --delete -R "$1" "$2" "$3" | grep -E \ '^deleting|[^/]$' >> /var/log/rsync.log
|
特別な場合で、&&
直後に中断する||
場合は\
オプションです。または:rsync -av --delete -R "$1" "$2" "$3" | grep -E '^deleting|[^/]$' >> /var/log/rsync.log
前述のように、この関数は常に3つの引数で呼び出されると仮定します。この仮定は非現実的なようです。コマンドを実行し
rsync
てすべての引数を関数に渡すには、次のようにします"$@"
。rsync -av --delete -R "$@" | grep …
grep
たとえば、引数を引数として使用するように関数を変更したい場合my_rsync_grep --exclude=代替/etc//backup.raw/(他のパラメータ)「^削除| [^ /] $」
次のことができます。
my_rsync_grep() { nargs=$(($#-1)) rsync -av --delete -R "${@:1:nargs}" | grep -E "${@:$#}" >> /var/log/rsync.log }
よりパラメータ拡張部分大きな打撃(1)
$@
などの構文に関する追加情報。${parameter:offset:length}
注:この構文はで動作しない可能性があります
bash
。