Pad*_*dau 16 shell-script quoting yad
管道和重定向是 Linux 中两个最强大的功能,我喜欢它们。
但是,我遇到了一种情况,我需要在不使用管道、重定向或函数的情况下将一段固定的文本写入文件。
我正在使用 Bash 以防万一。
如果有更简单的解决方案,我会解释原因。
我有一个带有一些菜单条目的后台 yad 通知。在某些菜单项中,我希望通知将一段固定的文本写入文件。这是我的意思的一个例子。
yad --notification --command=quit --menu='Example!echo sample >text.txt'
Run Code Online (Sandbox Code Playgroud)
问题是 yad 不接受重定向,所以它从字面上打印字符串sample >text.txt
而不是重定向。
同样,管道符号 ( |
) 是 yad 中的分隔符;但是如果你改变它,yad 会把它当作一个文字字符。例如:
yad --notification --command=quit --separator='#' --menu='Example!echo sample | tee text.txt'
Run Code Online (Sandbox Code Playgroud)
这从字面上打印字符串sample | tee text.txt
而不是管道。
编写一个供 yad 调用的函数也没有意义,因为 yad 运行在它自己的空间中并且无法识别该函数。
因此,我想要一个像echo
,cat
或者printf
将输出文件作为参数而不是重定向的命令。我已经搜索过这样的命令,但找不到。
当然,我可以自己编写并将其放在默认路径中:
FILENAME="${1}"
shift
printf '%s\n' "${*}" >"${FILENAME}"
Run Code Online (Sandbox Code Playgroud)
进而
yad --notification --command=quit --menu='Example!myscript text.txt sample'
Run Code Online (Sandbox Code Playgroud)
但是,如果 Linux 还没有这样的东西,我确实会感到惊讶!
谢谢
Gil*_*il' 32
这有点像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
prints foo
,而不是尝试执行程序echo foo
,这不是 yad 所做的。echo >filename
prints >filename
,而不是filename
write to ,这不是 yad 所做的。查看源代码,将popup_menu_item_activate_cb
调用 Glib 函数的操作传递给它g_spawn_command_line_async
。此函数使用g_shell_parse_argv
which 具有以下行为拆分给定的字符串,这几乎从来不是可取的,但可以解决:
将命令行解析为参数向量,与 shell 的方式大致相同,但没有 shell 将执行的许多扩展(不支持变量扩展、globs、运算符、文件名扩展等)。结果被定义为与您从 UNIX98 /bin/sh 获得的结果相同,只要输入不包含任何不受支持的 shell 扩展。如果输入确实包含这样的扩展,它们将按字面传递。
因此,您可以通过使用前缀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'"
Run Code Online (Sandbox Code Playgroud)
如果你想使用 shell 的特性,那么运行一个 shell:
yad --notification --command=quit --menu='Example!sh -c "echo sample >text.txt"'
Run Code Online (Sandbox Code Playgroud)