管道和重定向是 Linux 中最强大的两个功能,我喜欢它们。
然而,我遇到了这样的情况:我需要在不使用管道、重定向或函数的情况下将固定的文本写入文件。
我使用 Bash,以防万一。
第一:为什么?
如果有更简单的解决方案,我会解释原因。
我有一个带有一些菜单条目的背景 yad 通知。在某些菜单项中,我希望通知将固定的文本写入文件。这是我的意思的一个例子。
yad --notification --command=quit --menu='Example!echo sample >text.txt'
问题是 yad 不接受重定向,因此它实际上打印字符串sample >text.txt
而不是重定向。
同样,管道符号 ( |
) 是 yad 中的分隔符;但如果你改变它,yad 会把它当作一个字面字符。例如:
yad --notification --command=quit --separator='#' --menu='Example!echo sample | tee text.txt'
这实际上打印字符串sample | tee text.txt
而不是管道。
编写一个函数供 yad 调用也是没有意义的,因为 yad 在它自己的空间中运行并且不识别该函数。
因此我的问题
echo
因此,我想要一个像,cat
或者那样的命令,printf
它将输出文件作为参数而不是重定向。我已经搜索过这样的命令但找不到它。
当然,我可以自己编写并将其放在默认路径中:
FILENAME="${1}"
shift
printf '%s\n' "${*}" >"${FILENAME}"
进而
yad --notification --command=quit --menu='Example!myscript text.txt sample'
但是,如果 Linux 还没有这样的东西,我确实会感到惊讶!
谢谢
答案1
这有点XY问题但幸运的是,您已经解释了真正的问题,因此可以给出有意义的答案。
当然,有些命令可以将文本写入文件,而无需依赖其环境来打开文件。例如,sh
可以这样做:向其传递参数-c
和echo text >filename
。
请注意,这做满足此处“无重定向”的要求,因为 的输出sh
不会重定向到任何地方。运行的程序内部有一个重定向sh
,但这没关系,这只是sh
工作原理的内部细节。
但这能解决你的实际问题吗?您的实际问题是从 yad 操作将文本写入文件。为了解决这个问题,您需要确定什么是 yad 操作。不幸的是,手动的没有记录这一点。它所说的只是
menu:STRING
设置通知图标的弹出菜单。
STRING
必须在形式上name1[!action1[!icon1]]|name2[!action2[!icon2]]...
。空名称将分隔符添加到菜单。值的分隔符(例如|
)与参数一起设置--separator
。菜单项的分隔符(例如!
)用参数设置--item-separator
。
操作是一个字符串,但 Unix 命令是一个字符串列表:命令名及其参数。有几种可行的方法可以将字符串转换为命令名称及其参数,包括:
- 将字符串视为命令名称并在不带参数的情况下调用它。由于
echo foo
打印foo
而不是尝试执行程序echo foo
,这不是 yad 所做的。 - 将字符串传递给 shell。由于
echo >filename
打印>filename
而不是写入filename
,这不是 yad 所做的。 - 一些自定义字符串分割。此时,这大概就是 yad 所做的事情,但根据它具体是如何做的,您的问题的解决方案可能会有所不同。
看着源代码,动作被传递到popup_menu_item_activate_cb
它调用 Glib 函数g_spawn_command_line_async
。该函数使用分割给定的字符串g_shell_parse_argv
它具有以下行为,这几乎不是我们所希望的,但可以解决:
将命令行解析为参数向量,与 shell 的方式大致相同,但没有 shell 将执行的许多扩展(不支持变量扩展、通配符、运算符、文件名扩展等)。只要输入不包含任何不支持的 shell 扩展,结果就定义为与从 UNIX98 /bin/sh 获得的结果相同。如果输入确实包含此类扩展,则它们会按字面意思传递。
sh -c '
因此,您可以通过添加前缀并以 结尾来运行 shell 命令'
。如果您需要在 shell 命令中使用单引号,请编写'\''
。或者,您可以通过以 为前缀sh -c "
、以 结尾并在命令中出现的"
任何字符之前添加反斜杠来运行 shell 命令。"$\`
请注意嵌套引用,因为该操作本身在调用 yad 的 shell 脚本中被引用。
yad --notification \
--menu='Simple example!sh -c "echo sample text >text.txt"' \
--menu='Single-double-single quotes!sh -c "echo '\''Here you can put everything except single quotes literally: two spaces, a $dollar and a single'\''\'\'''\''quote.'\'' >text.txt"' \
--menu="Double-single-double quotes!sh -c 'echo \"Here punctuation is a bit tricky: two spaces, a \\\$dollar and a single'\\''quote.\"' >text.txt'"
答案2
如果您想使用 shell 的功能,请运行 shell:
yad --notification --command=quit --menu='Example!sh -c "echo sample >text.txt"'
答案3
一个简单的自定义脚本就可以了,例如printto.py
:
#!/usr/bin/python
import sys
if len(sys.argv) == 3:
f = open(sys.argv[1], "w")
f.write(sys.argv[2])
f.close()
else :
print("usage: printto.py file message")
sys.exit(1)
答案4
我想知道“yad”是否会作为括号内的子进程/子shell运行,以及是否可以从子进程重定向:
( yad BLAH BLAH BLAH ) > output.txt
或者
( yad BLAH BLAH BLAH ) >& output.txt