後でリモートサーバーで実行できるように、コマンドを変数に保存しようとしています。アスタリスクはフォルダ名に置き換えられ、変数に保存されます。後で使用するためにアスタリスクと同じコマンドが必要です。
スクリプト:
#!/bin/bash
cmd="ls -lrt /client/*/ver* /client/*/*/ver* | grep 299 | tail -1"
echo $cmd
出力:
./script.sh
ls -lrt /client/folder299/version_1 /client/ifolder299/ifolder/version_a /client/ifolder300/ifolder1/version_b /client/ifolder301/ifolder2/version_c /client/ifolder302/ifolder3/version_d | grep 299 | tail -1
周りを見回したが運がなかった。誰かがコマンドをそのまま保存する方法を見つけるのに役立ちますか?
答え1
コマンドは評価されず、文字列はそのまま変数に格納されます。引用符のない変数を出力すると、ワイルドカードパターンが拡張されます。
cmd="ls -lrt /client/*/ver* /client/*/*/ver* | grep 299 | tail -1"
これは安全で、cmd
リテラル文字列として設定できますls -lrt /client/*/ver* /client/*/*/ver* | grep 299 | tail -1
。この場合、文字列の周囲に二重引用符と一重引用符を使用することの違いは重要ではありません(ただし、静的文字列なので一重引用符を使用します)。シェルが文字列で拡張を実行する必要がないという点では重要ではありません。文字列に変数またはコマンド置換がある場合、シェルはそれを拡張しますが、実際には何もしません。
時出力変数値を使用すると、echo $cmd
ワイルドカードパターンが拡張されますが(これが発生します)、コマンドはまだ実行されません。
ワイルドカードパターンの拡張を防ぐには、変数を二重引用符で囲んで展開します"$cmd"
。個人的に
printf '%s\n' "$cmd"
その値を印刷します。望むより」なぜprintfがechoより優れているのですか?「なぜ。
関連:
また、解析中なのでls -l
(自安全ではない)次に番号を見つけます。どこかに出力にはls -l
ファイルサイズなどがあります。
解決しようとする大きな問題が何であるかをもう一度考えて、まったく新しい質問をしてみることを提案します。それ代わりに。
パス名リストで最近変更された一般ファイルを見つけるには、次のようにします。
unset newest
for pathname in /client/*/ver* /client/*/*/ver*; do
if [ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
newest=$pathname
fi
done
これは、前述のファイル名globbingパターンが解決したい名前に拡張されていると仮定します。また、文字列を含むファイル名のみを許可するように制限します299
。
unset newest
for pathname in /client/*/ver* /client/*/*/ver*; do
if [[ "${pathname##*/}" == *299* ]] &&
[ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
newest=$pathname
fi
done
ワイルドカードパターンが再帰的に見なければならないディレクトリに拡張される場合は、次のようにしますbash
。
shopt -s globstar
unset newest
for pathname in /client/*/ver*/** /client/*/*/ver*/**; do
if [[ "${pathname##*/}" == *299* ]] &&
[ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
newest=$pathname
fi
done
SSHを介してこの例を実行します。
ssh user@host bash -s -O globstar <<'END_SCRIPT'
for pathname in /client/*/ver*/** /client/*/*/ver*/**; do
if [[ "${pathname##*/}" == *299* ]] &&
[ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
newest=$pathname
fi
done
printf 'Newest file: %s\n' "$newest"
END_SCRIPT
答え2
おそらくオプションf:
$ touch /tmp/filetmp
$ c="ls /tmp/*"
$ set -f
$ echo $c
ls /tmp/*
$ set +f
$ echo $c
ls /tmp/filetmp
$ rm /tmp/filetmp
$ unset c
Linuxでは通常、デフォルトのオプションは+ fです。
答え3
上記のように混乱したことをお詫び申し上げます。
次のようにコマンドを直接入力すると、問題を解決できます。
ssh username@host "ls -lrt /client/*/ver* /client/*/*/ver* | grep $4 | tail -1"
答え4
コマンドを変数に保存するときは、単一引用符を使用してください。echo
コマンドで使用するときは二重引用符を使用してください。
$ cmd='ls -lrt /var/* /tmp/* /home/* | grep test | tail -1'
$ echo "$cmd"
ls -lrt /var/* /tmp/* /home/* | grep test | tail -1