英文:
Challenging: Ignore special characters in bash script
问题
我有一个非常简单的脚本,它会在屏幕上打印出传递给它的第一个参数,但字符串总是显示错误。问题在于这个脚本是从另一个程序中调用的,并将一个变量作为第一个参数传递给该脚本,因此我无法修改字符串本身,只能修改如何调用或传递它。
例如:
var string=test@$134!'
ssh user@server ./echo_string.sh #string#
#string# 是我将变量传递给shell脚本的方式,这将被替换为 test@$134!'
,但它不会显示在日志中,也不会被打印出来。
当我使用 ./echo_string.sh #string#
调用脚本时,我期望的输出是这样的:
test@$134!'
请注意,上述只是一个示例,字符串可以在任何位置包含任何特殊字符。
英文:
I have a very simple script that prints on screen what ever passed to it on the first argument, the string always come out wrong, and the problem is that this script is being called from another program and passes a variable to that script as the first argument, so there is no way for me to alter the string itself, but only how it is being called or passed.
e.g.
var string=test@$134!'
ssh user@server ./echo_string.sh #string#
#string# is how I'm passing the variable to shell script, this get replaced with test@$134!'
, but it doesn't show on the logs and never gets printed.
When I call the script with ./echo_string.sh #string#
the output the I'm looking for is this
test@$134!'
Kindly note that the previous is just an example and the string can have any special characters at any position
答案1
得分: 1
以下是您要翻译的部分:
如果是这种情况,那么该应用程序必须更加努力地转义test@$134!'
- 它需要转义$
,'
和!
,也许还需要转义@
和其他一些字符,如果它们存在于popen
shell的解释中。也就是说,调用popen("yourscript.sh test\@\$134\!\'")
。根据语言的不同,您可能需要双重转义这些字符,以确保语言字符串处理器不会消耗反斜杠:popen("yourscript.sh test\\@\\$134\\!\\'")
- 如果调用者是C或C ++,则需要这样做。
在许多情况下,只需在参数周围使用显式双引号就足够了,因为这会导致许多shell转义不会尝试 - 但因为您的字符串包含美元符号($),所以某些或所有短语可能会被解释为shell变量。在短语周围使用单引号是更强大的反处理器,但然后您字符串中的单引号会成为问题。也许使用引号包装程序会减少您需要转义的符号数量(单引号用于单引号,美元符号和双引号用于双引号)。
如果调用程序正在使用类似exec({"yourscript.sh", "test@$134!'""})
的参数数组API,并且文档说明调用是直接的,没有shell的话,那么在脚本中被解释之前,参数不会有风险,但您可能希望从调用程序中直接调用脚本解释器:exec({"/bin/bash", "yourscript.sh", "test@$134!'""})
。
那么问题可能出现在您的脚本中。您需要确保每次使用$1
时都将其引用为"$1"
以确保它不会扩展。如果将$1
复制到一个命名变量中,那么请记住始终引用它。
您可能需要同时执行这两个修复。
如果您担心参数可能被解释为命令选项,则需要检查您正在使用的命令的语法。许多命令支持一个特殊的--
选项,用于抑制选项处理。但有些不支持。我不确定是否有一种合法的方法来将字符串"-E"
作为单个命令进行echo
。尽管echo
试图很慷慨,如果它看到任何不是选项的字符,它会打印整个单词,因此echo -End
在bash中运行正常。Bash还支持printf命令,因此您可以使用它:printf "%s\n" "-e"
- 任何选项都必须位于格式字符串之前,因此注入不会被误解。
英文:
So is the other program simply calling popen("yourscript.sh test@$134!'")
or a similar API call that uses a single string?
If this is the case then that application must work harder to escape test@$134!'
- it needs to escape the $
the '
and the !
perhaps also the @
and certain other characters if they are present against the popen shell performing interpretation. I.e. call popen("yourscript.sh test\@\$134\!\'")
. Depending on the language you may have to double-escape these characters to ensure the language string processor does not consume the backslash: popen("yourscript.sh test\\@\\$134\\!\\'")
- you would need this if the caller was C or C++.
In many cases, simply using explicit double-quotes around the argument would be enough, as that causes many shell escapes to not be attempted - but because your string contains a dollar sign ($) some, or all of the phrase might be interpreted as a shell variable. Using single quotes round the phrase is an even more powerful anti-processor, but then the single quote you have in the string is an issue. Perhaps using a quotes wrapper reduces the number of symbols that you then need to escape (singlequote for singlequote vs $ and doublequote for doublequote)
If that caller program is using an array of arguments API like exec({"yourscript.sh", "test@$134!'"})
and the documentation says the call is direct with no shell, then there is no risk of the argument being interpreted before it gets to your script, but you may want to directly call the script interpreter from the caller program: exec({"/bin/bash", "yourscript.sh", "test@$134!'"})
.
Then the problem probably is in your script. You need to ensure that whenever you use $1 you quote it as "$1" to ensure that it is not expanded. If you copy the $1 to a named variable then remember to quote that always.
You may need to do both these fixes.
If you are concerned that the argument might be interpreted as a command option, then you need to check the syntax of the commands you are using. Many commands support a special --
option which suppresses the option processor. But some do not. I'm not sure if there is a legal way to echo
the string "-E" as a single command. Though echo
does try to be generous and prints the whole word if it sees any characters that are not options, so echo -End
works fine (in bash). Bash also supports a printf command, so you could use that: printf "%s\n" "-e"
- any options have to be before the format string, so the injections cannot be misinterpreted.
答案2
得分: 0
尝试这个:
var string = 'test@$134!\'"';
- 我使用单引号转义了"!"
- 我在末尾添加了一个单引号和"'"
在我的shell中,变量打印出与您想要的完全相同。
英文:
try this pls:
var string='test@$134!'"'"
- Im escaping "!" with single quote
- Im adding a single quote at the end with "'"
In my shell, the variable print exactly as you want.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论