stdinから読み込み、ファイルに書き込むUnixコマンドはありますか(例:出力をstdoutに送信せずにtee)。

stdinから読み込み、ファイルに書き込むUnixコマンドはありますか(例:出力をstdoutに送信せずにtee)。

あるシステムから別のシステムに読み書きするためにルートが必要なファイルをコピーしたいと思います。私の現在の解決策は、各システムでsudoを使用し、示されているようにteeを使用することです。

ssh host sudo cat /etc/somefile | sudo tee /etc/somefile > /dev/null

teeこれは機能しますが、teeは入力をstdoutに送信するため、出力を/ dev / nullに送信する必要があります。

catUNIXとコピーコマンドを見ましたが、cp答えが見つかりませんでした。
バラよりhttps://man7.org/linux/man-pages/man1/cp.1.html
そしてhttps://man7.org/linux/man-pages/man1/cat.1.html


sudo更新:今、このソリューションにはサポートが必要なので、単純な使用ソリューションは機能しないことを明示する必要catがあることに気づきました。

例えば、

ssh host sudo cat /etc/somefile | sudo cat > /etc/somefile

ディレクトリ/etcはルート(私の場合)のみを書き込むことができ、ファイルリダイレクトは> /etc/somefile現在のユーザー(/ etcに書き込む権限がないユーザー)で実行されるため失敗します。

答え1

持っている:

sh -c 'exec cat > file'

または、すべての$filesに対して環境変数として渡されます。

sudo FILE="$file" sh -c 'exec cat > "$FILE"'

またはパラメータとして:

sudo sh -c 'exec cat > "$1"' sh "$file"

sh入るインラインスクリプトの内容$0$file$1

(以下で開く>>代わりに参照してください。>追加モードまたは1<>切り捨てなしで(そして読み取り+書き込みモードで)開いてファイルを所定の位置に上書きします(dd's conv=notrunc)。

とにかくいいえする:

sudo sh -c "cat>$file 実行"

$fileシェル構文に特殊文字(スペースなど;)を含めると失敗し、$コマンドインジェクションの脆弱性が発生するためです。


さらに:

dd bs=65536 of=file

(転送レポートを抑制するためにstatus=noneGNUと互換性があるか実装されていますdd。ファイルを開く方法を制御するための多くのオプションがあり、そのリストは実装によって異なりますdd。)


ほとんどのシステムでは:

cp /dev/stdin file

moreutilsもっとある

sponge file

sort少なくともGNUを使用し、テキスト入力時:

sort -mo file

テキスト入力(またはsedテキスト以外のものを処理できる実装)を使用してください。

sed -n 'w file'

テキスト入力を使用する:

awk '{print > "file"}'

またはGNUを使用してくださいawk

gawk -v ORS= '{print $0 RT > "file"}'

sshここからルートとしてローカルファイルを開き、通常のユーザーとして実行することもできます。

sudo zsh -c '
  USERNAME=$SUDO_USER ssh host 'sudo cat /etc/somefile' > /etc/somefile'

これは、データが追加のパイプを通過する必要がないことを意味します。

また、すぐに圧縮を使用xzし、pixzファイルへの解凍サポートを使用してローカルに解凍することもできます。

ssh host 'sudo xz -0 -c /etc/somefile' | sudo pixz -tdo /etc/somefile

答え2

複数のファイルが存在し、ターゲットの同じ場所にある必要がある場合は、tarここでファイルを別のディレクトリにコピーできますが、パイプも何らかのssh方法で関連付けることができます。それでも問題が解決しない場合は、pファイル権限または一部の圧縮フラグを保持できます。ssh

$ mkdir output
$ echo foo > foo
$ echo bar > bar
$ tar cf - foo bar | ( cd output && tar xf - )
$ cat output/*
bar
foo

tar実装がシステムによって異なる場合、移植性の問題が発生する可能性があります。

答え3

cat要件に従う最も簡単な手順です。特に、cat -標準入力からデータを読み取るようにコマンドに指示します。

sudoパイプコマンドの左側は明確ではありません/etc/somefile。答えに対する最善の推測は次のとおりです。

sudo cat /etc/somefile | ssh me@otherhost 'sudo cat - > /etc/somefile'

関連情報