Linux 一种防止bash使用转义符号解析带out的命令行的方法

Linux 一种防止bash使用转义符号解析带out的命令行的方法,linux,bash,shell,command-line,command-line-arguments,Linux,Bash,Shell,Command Line,Command Line Arguments,我正在寻找一种方法(除了“.”、\)来使用bash(或任何其他linux shell),同时防止它解析命令行的某些部分。这个问题似乎无法解决 理论上,一个简单的开关就足够了(例如-x…告诉你 字符串…不会被解释)但它显然不存在。我想知道是否有一个解决这个问题的方法,黑客或想法。最初的问题是将youtube URL(可能包含特殊字符(&,等等))作为参数的程序的脚本别名。这个问题甚至更加困难:在扩展“$1”的同时阻止shell解释扩展的字符串——本质上,在不解释其结果的情况下扩展“$1”使用:

我正在寻找一种方法(除了“.”、\)来使用bash(或任何其他linux shell),同时防止它解析命令行的某些部分。这个问题似乎无法解决

理论上,一个简单的开关就足够了(例如-x…告诉你 字符串…不会被解释)但它显然不存在。我想知道是否有一个解决这个问题的方法,黑客或想法。最初的问题是将youtube URL(可能包含特殊字符(&,等等))作为参数的程序的脚本别名。这个问题甚至更加困难:在扩展“$1”的同时阻止shell解释扩展的字符串——本质上,在不解释其结果的情况下扩展“$1”

使用:


myprogram简短回答:您不能这样做,因为shell在决定脚本/别名/将要运行的内容之前就解析命令行(并解释“&”)了,更不用说脚本有任何控制权了。等到你的剧本在这个过程中有任何影响的时候,已经太晚了

不过,在脚本中,很容易避免大多数问题:将所有变量引用用双引号括起来。例如,与其使用
curl-o$outputfile$url
,不如使用
curl-o“$outputfile”“$url”
。这将防止shell在将变量的内容传递到命令(/other script/whatever)之前对其应用任何解析


但是当您运行脚本时,您总是必须引用或转义命令行上传递的任何内容。

您的规范仍然不是很清楚。据我所知,问题是你想彻底改造shell处理参数的方式。所以…你必须自己编写shell。基础知识甚至没有那么难。以下是伪代码:

while true:
    print prompt
    read input
    command = (first input)
    args = (argparse (rest input))
    child_pid = fork()
    if child_pid == 0: // We are inside child process
        exec(command, args) // See variety of `exec` family functions in posix
    else: // We are inside parent process and child_pid is actual child pid
        wait(child_pid) // See variety of `wait` family functions in posix

您的问题基本上归结为“argparse”函数是如何实现的。如果它只是一个标识函数,那么就根本没有展开。这就是你想要的吗?

我很难理解你的问题。你能举个例子吗?从stdin读取URL,而不是从命令行。如果你想自动完成任务(见我问题的最后一句),从stdin读取URL是不可能的。从stdin读取URL始终是一个选项。管道就是这样工作的。如果您的脚本无法处理它,您可以使用
xargs
使其播放效果更好。@jaamlysi不,他们没有;你误解了在哪一步发生了什么。当您的脚本获得
$1
时,它已经被解析(即解释特殊字符),现在返回并取消解析它已经太晚了。当您使用
$1
时,防止任何进一步的解析很容易——正如我所说的,用双引号(
“$1”
)将其括起来。但这与取消shell在调用脚本之前所做的解析不同,而且根本无法返回并取消。Bash不会解释here doc中的特殊字符,即使EOF没有被单引号括起来。@OlegAndriyanov-半正确。变量和进程替换仍然适用。@OlegAndriyanov你错了。如果开头的EOF没有用单引号括起来,Bash会将
$string
解释为变量
string
。命令替换、进程替换和算术扩展也会发生。@hek2mgl这对我来说是新的。谢谢很好的尝试,但这相当于“.”-ing。参见问题的最后两句,了解一些(现实世界中更难的)问题examples@hek2mgl你能说得更具体一点吗?也许你没有回答这个问题——我承认这很难回答。但是,使用我发布的here doc解决方案可以将输入传递到脚本而不受shell解析的约束。由于问题似乎越来越不清楚,因此还原了否决票。@hek2mgl我也不完全清楚实际的问题是什么,但我认为我的答案是正确的:没有办法避免在命令行上进行解析。您的答案通过stdin而不是在命令行上传递URL来避免这个问题。但在我看来,这对将URL传递给脚本的用户最有用;在脚本中,双引号非常有效。双引号不起作用,因为变量名、命令替换和好友会被扩展。我会使用单引号。但我仍然认为用户关心向脚本传递数据IMHO使用stdin是最好的方法。以需要读取任意数据的
gpg
命令为例,它从stdin读取数据。
while true:
    print prompt
    read input
    command = (first input)
    args = (argparse (rest input))
    child_pid = fork()
    if child_pid == 0: // We are inside child process
        exec(command, args) // See variety of `exec` family functions in posix
    else: // We are inside parent process and child_pid is actual child pid
        wait(child_pid) // See variety of `wait` family functions in posix