この方法でターゲットファイルとやり取りするシェル(php
)スクリプトがあります。
php
のis_writable()
で書き込み可能かどうかを検査します(これは問題ではないと思います)sed
コマンドを使用してインプレースファイル編集を行います。grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n"
結果として、私は(他はすべて正しいが)myuser:www-data
することが myuser:myuser
。
sed
はファイルグループの所有権を変更しているように見えますが、可能であればそれを回避するにはどうすればよいですか?
sed
のインプレース編集モード-i
には少し問題があります。 sed
は、同じディレクトリにsedy08qMA
という一時ファイルを作成します。ここで、y08qMA
はランダムに生成された文字列です。そのファイルは、元のファイルの変更された内容で埋められます。操作後、sed
は元のファイルを削除し、一時ファイルの名前を元のファイル名に変更します。したがって、それは本当のinplace editではありません。呼び出し元ユーザーのアクセス許可と新しいiノード番号を含む新しいファイルを作成します。その振る舞いはほとんど悪くはありませんが、例えば、ハードリンクが壊れてしまいます。
ただし、trueインプレース編集が必要な場合は、ed
を使用する必要があります。 stdinからコマンドを読み取り、一時ファイルなしでファイルを直接編集します(これはed
のメモリバッファに対して行われます)。一般的な方法は、printf
を使用してコマンドリストを生成することです。
printf "%s\n" '1,$s/search/replace/g' wq | ed -s file
printf
コマンドは、次のような出力を生成します。
1,$s/search/replace/g
wq
これらの2行はed
コマンドです。最初のものは文字列search
を検索し、それをreplace
に置き換えます。 2つ目は、ファイルへの変更を書き込み(w
)、終了します(q
)。 -s
は診断出力を抑制します。
ed
の代わりにsed
を使用することは、追加の入力をパイプする必要があることを考えると、これにはかなり不必要に思えます。現在取り組んでいるディストリビューション(CentOS 5.10)には、-c
オプションがあり、sed
に-i
オプションがあります。 _オプション。私はそれをテストしましたが、インライン編集を行うときに元の所有者とグループを維持しながら、完全に機能しました。変更時間は保持されません。
例:sed -ci -e '3,5d' file.txt
-c
は、名前の変更ではなくコピーを使用します(つまり、所有権/グループを保持します)-i
インライン編集-e
実行するスクリプト/式このオプションが他のディストリビューション全体でsed
にどれだけ普及しているかはわかりません。 Solaris 10にはありませんでしたが、Solarisには欲しいものがたくさんありません。