LEMPスタックを備えたUbuntu16.04(xenial)でBash 4.3.48(1)を使用しています。
php.ini
を作成しようとしています printf
を使用してバージョンに依存しない方法でファイルをオーバーライドする 。
1) バージョンに依存しない操作は失敗します:
printf "[PHP]n post_max_size = 200Mn upload_max_filesize = 200Mn cgi.fix_pathinfo = 0" > /etc/php/*/fpm/zz_overrides.ini
次のエラーが発生します:
bash:/etc/php/*/zz_overrides.ini:そのようなファイルやディレクトリはありません
2) バージョングノーシス操作は成功します:
printf "[PHP]n post_max_size = 200Mn upload_max_filesize = 200Mn cgi.fix_pathinfo = 0" > /etc/php/7.0/fpm/zz_overrides.ini
ご覧のとおり、*
以外は基本的に同じです。 vs 7.0
。
-
man printf
で、この(正規表現?)問題についての手がかりが見つかりませんでした 。 - Googleで検索したところ、「printfで正規表現を許可する」ことについて何も見つかりませんでした。
バージョンに依存しない操作が失敗し、バイパスがあるのはなぜですか?
編集:可能であれば、1行の操作を使用することが最も重要です。
承認された回答:
リダイレクションでのパターンマッチの動作は、シェル間で異なるように見えます。私のシステムにあるもののうち、dashとksh93はパターンを展開しないため、リテラルの*
を含むファイル名を取得します。 。 Bashはそれを展開しますが、パターンが1つのファイルに一致する場合に限ります。一致するファイル名が他にもある場合は文句を言います。 Zshは、複数のリダイレクトを指定したかのように機能し、出力をすべてにリダイレクトします。 一致するファイル。
(1)非対話型でPOSIXモードの場合を除く
一致するすべてのファイルに出力を送信する場合は、tee
を使用できます。 :
echo ... | tee /path/*/file > /dev/null
1つのファイルだけに移動する場合、問題はどちらを使用するかを決定することです。パターンに一致するファイルが1つだけであることを確認する場合は、リスト全体を展開して数えます。
bash / kshの場合:
names=(/path/*/file)
if [ "${#names[@]}" -gt 1 ] ; then
echo "there's more than one"
else
echo "there's only one: ${names[0]}"
fi
標準シェルでは、set
位置パラメータと$#
を使用します カウントのために。
もちろん、パターンがどのファイルとも一致しない場合は、そのまま残されます。グロブは中央にあるため、結果は存在しないディレクトリを指します。 /path/to/file
を作成しようとするのと同じです 、/path/to
の前 存在します。ここに/path/*
があります。 代わりに、文字通り、アスタリスクを付けます。
これに対処するには、ファイル名なしでディレクトリ名を展開してから、すべてのディレクトリにファイル名を追加する必要があります。これは少し醜いです…
dirs=(/path/*)
files=( "${dirs[@]/%//file}" )
次に、その配列を使用できます:
echo ... | tee "${files[@]}" > /dev/null
または、簡単な方法でファイル名パターンをループすることもできます。より一般的なケースでは、出力ファイルごとにメインコマンドを1回実行するか、一時ファイルを使用して出力を保持する必要があるため、少し不十分です。
for dir in /path/* ; do
echo ... > "$dir/file"
done