私が望むものfile2
の内容と一致すれば、file1
明らかに実行できますcp file1 file2
。
しかし、私が守りたいならすべて~についてfile2
とは別にコンテンツ - 所有者、権限、拡張属性、ACL、ハードリンクなどを実行したくありません。cp
*この場合は。file1
file2
次はこのトリックを実行するようです。
< file1 > file2
しかし、これはうまくいきません。 file2
null に切り捨てられ、記録されません。しかし、
cat < file1 > file2
する働く
驚いたことに、最初のバージョンは動作しませんでした。
2番目のバージョンはUUOCですか?リダイレクトを使用してコマンドを呼び出さずにこれを行う方法はありますか?
注:私はUUOCが実際のアンチパターンではなく、賢明な意見に近いことを知っています。
*ようにtniles09発見、cp
〜するこの場合は実際に動作します。
答え1
cat < file1 > file2
UUOCではありません。通常、システムレベルのファイル記述子の複製に対応するリダイレクトが<
行われます。>
ファイル記述子の複製自体は何もしません(まあ、>
リダイレクトはopenを使用するので、O_TRUNC
正確に言えば、出力リダイレクトは出力ファイルを切り捨てます)。この<
>
記号を混同しないでください。リダイレクトはデータを移動しませんが、ファイル記述子を別のファイル記述子に割り当てます。
この場合、file1
対応するファイル記述子を開き、それをファイル記述子0
(<file1
== 0<file1
)に割り当て、次にfile2
そのファイル記述子をファイル記述子1
(>file2
== 1>file2
)に割り当てます。
2 つのファイル記述子があるので、2 つのファイル記述子間でデータを移動するプロセスが必要です。これがまさに目的ですcat
。
答え2
他の人が指摘したように、問題の動作はシェルによって異なるため、そうではありません。あなた(OP)が指摘したように、これは少しです賢い、さらに気分?、ある種のテーマ。
ただし、GNUシステムには、初期の前提に使用できる別のソリューションがありますcp --no-preserve=all file1 file2
。試してみてください。説明した状況(file2
属性を変更せずにコンテンツを変更するなど)を満足させると思います。
はい:
$ ls -l
total 8
-rw-r--r-- 1 tniles sambashare 16 Dec 16 12:21 fezzik
-rw-r--r-- 1 tniles tniles 14 Dec 16 12:16 fred
$ cat *
Lookout, world!
Hello, world!
$ cp --no-preserve=all fred fezzik
$ ls -l
total 8
-rw-r--r-- 1 tniles sambashare 14 Dec 16 12:22 fezzik
-rw-r--r-- 1 tniles tniles 14 Dec 16 12:16 fred
$ cat *
Hello, world!
Hello, world!
修正する
実際、またはcp
指定しない限り、私のシステム自体が属性を保持しているようです-a
。-p
私はbashシェルとGNU coreutilsを使用しています。毎日新しいことを学ぶと思います...
ワイルドカードによるテスト結果には、ハードリンクとさまざまな権限が含まれます。
$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete vagrant 39 Dec 16 20:35 file2
913965 -rwxrw---- 2 pete vagrant 39 Dec 16 20:35 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the original contents of file2
$ cp file1 file2
$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete vagrant 30 Dec 16 20:37 file2
913965 -rwxrw---- 2 pete vagrant 30 Dec 16 20:37 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the contents of file1
$
答え3
zsh
アクションシェルでは、< file1 > file2
シェルはを呼び出しますcat
。
リダイレクトのみが含まれ、コマンドまたは割り当ては含まれていないコマンドラインに対して(デフォルトで)呼び出されます。ただし、唯一のzsh
リダイレクトが1つの場合は(デフォルトで)呼び出されます。 (inまたはエミュレーションでない場合は、エミュレートするシェルのように動作します)。$NULLCMD
cat
<
$READNULLCMD
pager
zsh
sh
csh
だから:
< file1 > file2
実は同じ
cat < file1 > file2
そして
< file1
同じですか?
pager < file1
答え4
< file1 > file2
シェルに依存しているようです。 zshでは機能しますが、bashでは機能しません。
編集:間違った文を削除しました。