シェルなしでファイルに文字列を書き込む

シェルなしでファイルに文字列を書き込む

実行中のシェルがない環境があるため、リダイレクト、パイプ、ここのドキュメント、または他のシェル注意を使用できないとします。できるスタートコマンド(経由execvpまたは同様の方法)。名前付きファイルにランダムな文字列を書きたいです。以下を実行する標準コマンドはありますか?

somecommand  outputfile 'string'

たとえば、

somecommand /proc/sys/net/ipv4/ip_forward '1'

非常に愚かな例は次のとおりです。

curl -o /proc/sys/net/ipv4/ip_forward http://example.com/1.txt

その中に私が欲しい文字列を含めるように1.txtを設定しました。

これを悪用する可能性がある一般的なコマンドはありますか?

答え1

システムに空でない他のファイルがある場合は、次を使用します。POSIXsed:

sed -e 's/.*/hello world/' -e 'wtarget' -e q otherfile

GNUsedと空でないファイルを使用すると、次のことができます。

sed -i.bak -e '$ihello world' -e 'd' foo

BSDの場合、sed次のように動作します。

sed -i.bak -e '$i\
hello world' -e d foo

シェルを使用しない場合、改行文字は問題にならない可能性があります。


そしてex、ターゲットファイルが存在する場合:

ex -c '0,$d' -c 's/^/hello world/' -c 'x' foo

これはファイルのすべての内容を削除し、最初の行を「hello world」に置き換えてから書き込んで終了します。vi代替を使用して同じことを実行できますex。実装では複数のオプションをサポートする必要はありませんが、通常はサポートされてい-cます。多くのex実装では、ファイルがすでに存在する必要はありません。


返品そしてawk:

awk -v FN=foo -v STR="hello world" 'BEGIN{printf(STR) > FN }'

「foo」ファイルに「hello world」を書き込みます。


既存のファイルに既知の場所に目的のバイトが含まれている場合は、複数のコマンドでファイルをバイト単位で組み合わせることができますdd(この場合はalphabetアルファベットが含まれていますが、入力ファイルが混在する可能性があります)。

dd if=alphabet bs=1 skip=7 count=1 of=test
dd if=alphabet bs=1 skip=4 count=1 seek=1 of=test
dd if=alphabet bs=1 skip=11 count=1 seek=2 of=test
dd if=alphabet bs=1 skip=11 count=1 seek=3 of=test
dd if=alphabet bs=1 skip=14 count=1 seek=4 of=test
cat test
hello

これにより、ルーチンが正しくcp機能するか、すでに起動するのに適した場所にいる可能性があります。


あまり一般的には、mispipemoreutilsのコマンドシェルレスパイプラインの構築を許可します。

mispipe "echo 1" "tee wtarget"

同じecho 1 | tee wtargetですが終了コードを返しますecho。これは以下を使用します。system()これ内部的にはそうではありません厳しくシェルが存在する必要があります。


最後に、他の汎用スクリプト言語perlと同様に、コマンドラインで目的の操作を実行する任意のプログラムを作成できる汎用コマンドがあります。python同様に、シェルは「実行中」ではありませんが、存在する場合はsh -c 'echo 1 > target'正しく機能します。

答え2

あなたが使用できるawk

awk 'BEGIN {print "Hello" > "/tmp/file"}'

awkプログラムにステートメントが1つしか含まれていない場合は、入力を処理せずにBEGINそのステートメントのみを解釈します。

パラメータ化することもできます。

awk -v text="World" -v file="/tmp/main" 'BEGIN {print text > file}'

この構文を使用してもバックスラッシュ文字をエスケープする必要があります。以下の使用に問題はありませんARGV

awk 'BEGIN {print ARGV[1] > ARGV[2]}' World /tmp/main

関連情報