假设我有一个没有运行 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