【问题标题】:A way to prevent bash from parsing command line w/out using escape symbols一种防止 bash 在不使用转义符号的情况下解析命令行的方法
【发布时间】:2015-09-04 05:54:35
【问题描述】:

我正在寻找一种方法(除了“.”、“.”、\.)来使用 bash(或任何其他 linux shell),同时防止它解析命令行的某些部分。问题似乎无解 How to interpret special characters in command line argument in C?

理论上,一个简单的开关就足够了(例如 -x ... string ... 不会被解释)但它显然不存在。我想知道是否有解决此问题的解决方法、技巧或想法。最初的问题是一个程序的脚本|别名,它以 youtube URL(可能包含特殊字符(& 等))作为参数。这个问题更加困难:扩展 "$1" 同时阻止 shell 解释扩展的字符串——本质上是扩展 "$1" 而不解释其结果

【问题讨论】:

  • 我很难理解你的问题。你能举个例子吗?
  • 从标准输入读取 URL,而不是从命令行读取。
  • 如果要自动执行任务,则排除从标准输入读取 URL(请参阅我的问题的最后一句话)
  • 从标准输入读取始终是一种选择。这就是管道的工作原理。如果您的脚本无法处理它,您可以使用xargs 让它发挥作用。
  • @jaamlysi 不,他们没有;你误解了哪一步发生了什么。当您的脚本获得$1 时,它已经被解析(即解释了特殊字符),现在返回并取消解析它为时已晚。使用$1 时防止任何进一步的解析很容易——正如我所说,用双引号("$1")括起来。但这与撤消 shell 在调用脚本之前所做的解析不同,根本无法返回并撤消它。

标签: linux bash shell command-line command-line-arguments


【解决方案1】:

使用here-document

myprogramm <<'EOF'
https://www.youtube.com/watch?v=oT3mCybbhf0
EOF

如果您将起始 EOF 括在单引号中,bash 将不会解释 here-doc 中的任何特殊字符。

【讨论】:

  • 即使 EOF 没有被单引号括起来,Bash 也不会解释此处文档中的特殊字符。
  • @OlegAndriyanov - 对了一半。变量和流程替换仍然适用。
  • @OlegAndriyanov 你错了。如果开头的 EOF 没有用单引号括起来,Bash 会将 $string 解释为变量 string。还会发生命令替换、进程替换和算术扩展。
  • @hek2mgl 这对我来说是新的。谢谢!
  • 不错的尝试,但这相当于'.'-ing。有关一些(更困难的现实世界)问题示例,请参阅问题的最后 2 句
【解决方案2】:

简短的回答:你不能这样做,因为 shell 在决定你的脚本/别名/将要运行的内容之前解析命令行(并解释诸如“&”之类的东西),更不用说你的脚本有任何控制权了。当你的脚本对这个过程产生任何影响时,已经太晚了。

脚本中,但是,很容易避免大多数问题:将所有变量引用包含在双引号中。例如,您应该使用curl -o "$outputfile" "$url" 而不是curl -o $outputfile $url。这将阻止 shell 在将变量的内容传递给命令(/其他脚本/其他)之前对其进行任何解析。

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

【讨论】:

  • @hek2mgl 你能说得更具体点吗?
  • 可能你错过了这个问题 - 我承认这很难得到。但是,使用我发布的 here-doc 解决方案,可以将输入传递给脚本而不使输入受到 shell 解析
  • 撤回了反对票,因为问题似乎越来越不清楚。
  • @hek2mgl 我也不完全清楚实际的问题是什么,但我认为我的答案是正确的:没有办法避免在命令行。您的答案通过标准输入而不是命令行传递 URL 来避免这个问题。但是 IMO 这对于将 URL 传递给脚本的用户最有用;在脚本中,双引号效果很好。
  • 双引号不起作用,因为变量名称、命令替换和朋友会被扩展。我会使用单引号。但我仍然认为用户关心将数据 传递给 脚本。 ----恕我直言,使用标准输入是最好的方法。以gpg 命令为例,它需要读取任意数据——它从标准输入读取。
【解决方案3】:

您的规范仍然不是很清楚。据我所知,问题是您想完全重新发明 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”函数是如何实现的。如果它只是一个恒等函数,那么你根本不会得到扩展。这就是你想要的吗?

【讨论】:

    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 2012-09-14
    • 1970-01-01
    • 2014-01-07
    相关资源
    最近更新 更多