将字符串写入没有外壳的文件

将字符串写入没有外壳的文件

假设我有一个没有运行 shell 的环境,因此我无法使用重定向、管道、此处文档或其他 shell-ism,但我启动命令(通过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

如果您不使用 shell,那么换行可能不是问题。


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 }'

会将“hello world”写入文件“foo”。


如果现有文件在已知位置包含您想要的字节,您可以通过多个命令逐字节组装文件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即可工作,或者您可能已经能够将其放在适当的位置开始。


不太常见的是,mispipe来自 moreutils 的命令允许构建无壳管道:

mispipe "echo 1" "tee wtarget"

相当于echo 1 | tee wtarget,但返回退出代码echo。这使用system()在内部,这并不严格地需要一个外壳存在。


最后,perl是一个通用命令,可以让您编写任意程序在命令行上执行任何您想要的操作,就像python任何其他通用脚本语言一样。同样,如果 shell 没有“运行”,但它确实存在,sh -c 'echo 1 > target'则可以正常工作。

答案2

你可以使用awk

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

awk程序仅包含一条BEGIN语句时,它仅解释该语句而不处理任何输入。

您甚至可以参数化它

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

尽管使用该语法,您需要转义反斜杠字符。使用ARGV没有问题:

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

相关内容