私の関数(.bashrcに含まれています)の1つで次のコマンドを実行して、別のサーバーに保存されているファイルへのパスを見つけて変数に保存しようとしています。
FILE_PATH=$(ssh -T user@host 'find <directory> -name *<filename>*')
ただし、これは出力を返しません。スクラップした場所にファイルがあるかどうかを確認したり、コマンドラインからコマンドをコピーして出力値を変数に保存することも可能ですが、関数実行時には動作しませんね。
何が起こっているのか、コマンドが機能しない理由を知っている人はいますか?
編集する:
私が見ていることを次のように表現します。
function get_path {
FILE=$1
FILE_PATH=$(ssh -T user@hostB 'find /home/daverbuj -name *${FILE}*')
echo "Here is the file: ${FILE_PATH}"
}
[daverbuj@hostA]$ FILE_A=$(ssh -T user@hostB 'find /home/daverbuj -name foo.bar')
[daverbuj@hostA]$ echo $FILE_A
/home/daverbuj/foo.bar
[daverbuj@hostA]$ get_path foo.bar
Here is the file:
コマンドラインから実行すると期待される結果が表示されますが、関数を実行すると結果は表示されません。
答え1
get_path() {
local name=$1
readarray -td '' reply < <(
LC_FILE_NAME=$name ssh -o SendEnv=LC_FILE_NAME -n -T user@hostB '
LC_ALL=C find /home/daverbuj -name "*$LC_FILE_NAME*" -print0')
(( ${#reply[@]} )) &&
echo "File path${reply[2]+s} with that name:" &&
printf ' - %s\n' "${reply[@]}"
}
function f {...}
kshスタイル関数定義()を使用する必要はなく、bash
標準もサポートされています。f() compound-command
- 一致するファイルが複数ある場合があります。確実に区別するには、NULを区切り記号()として使用する必要があります
-print0
。bash
変数はNULを保持できませんが、バージョン4.4以降、組み込み関数readarray
はNULで区切られた入力ストリームを-d ''
。 *
find
グローバル演算子なので、名前パターン一致演算子に逐語的に渡すには、ローカルシェルとリモートシェルの両方に引用符を付ける必要があります-name
。- ローカルシェルは、変数をリモートシェルに渡されたコードに拡張したくありません。これは、ある種のランダム命令注入の脆弱性を構成するためです。代わりに、ここで環境変数を介してリモートシェルに
$name
値を渡しますLC_FILE_NAME
(sshd
設定されていると仮定)。リモートホストユニバーサルからAcceptEnv LC_*
)。コードでは、リモートシェルは変数$FILE
を拡張しますが(引用するのを忘れましたが*
)、ローカルシェルからリモートシェルに変数を渡しません。 $REPLY
for scalar と$reply
for array は変数名の一般的な規則であり、結果を呼び出し元に返します。- 任意のデータにはこれを使用できません
echo
(バックスラッシュが含まれていないか、で始まらないことを保証することはできません-
)。 -name '*foo*'
foo
fnmatch()
ファイル名を対応する文字セットにデコードできないと、sを使用してエラーが発生するため、マルチバイト文字セット(UTF-8など)を使用して名前のすべてのファイルを一致させることはできません。したがって、シングルバイトロケールで固定されています。find
-name
LC_ALL=C
- ここでは、少なくとも1つのファイルが見つかり、正しく印刷されない場合は失敗した終了ステータスを返します。
- 標準入力の入力を消費しないように
-n
オプションを使用します。無人処理に関連する調整をssh
追加することもできます。-o BatchMode=yes
ここでもっと読む:
答え2
stderr
パスをリセットしてstdout
使用できます。
OUT=$(ssh -tt -vv [email protected] "remote command" 2>&1 )
関数でこのような内容を編集すると正常に動作します!