目前我有一个 bash 脚本,其中我接受来自命令行的输入,但输入带有空格,并且 bash 脚本不读取空格后面的单词。脚本是这样的
#!/bin/bash
var1=$1
var2=$2
echo $var1
echo $var2
假设我将此文件保存为 test.sh。现在我的输入是这样的 -
./test.sh hi check1,hello world
输出是 -
hi
check1,hello
但我需要输出为
hi
check,hello world
PS:我无法提供双引号中的输入,所以我需要一些其他解决方案,可以用空格读取单词
答案1
那是不可能的。参数的单词拆分发生在脚本运行之前,因此当脚本启动时,参数已经被拆分为单词。阅读有关“分词”的内容,man bash
了解更多详细信息。
如果你知道将有 2 个参数,第一个参数永远不会包含空格,您可以通过某种方式解决它
#! /bin/bash
first=$1
shift
rest="$*"
printf '<%s>\n' "$first" "$rest"
但它仍然会将多个空间缩小为一个。
答案2
正如 @choroba 正确指出的那样,你不能这样做,至少不能开箱即用。
原因是:shell 在执行任何操作之前,解析在命令行中,这是一个通过几个明确定义的步骤进行的过程。这些步骤之一是“字段分割”,其中 shell 将输入行分割成不同的部分。考虑:
命令 arg1 arg2
shell 必须以某种方式确定“command”是命令,“arg1”是第一个参数,“arg2”是第二个参数,不是吗?必须有一个原因为什么“arg1”是第一个参数而不是“arg1 arg2”,或者为什么“command”是命令而不是“command arg1”,等等。
不,话虽如此,有两件事会影响这种拆分的完成方式:(shell )变量 IFS 和 OFS。 IFS(“内部字段分隔符”)是一个字符列表,如果未屏蔽,它将分隔字段。在上面的示例中,“arg1”与“arg2”和“command”之间用空格分隔 - 这是 IFS 的一部分。
您可以自己将 IFS 设置为任何字符(甚至是空字符串),但默认情况下(POSIX 文档中规定)它设置为“空白”、“制表符”和“换行符”。欲了解更多信息,请参阅了解 IFS。
在这个相当冗长的一般性介绍之后,这对您的问题意味着什么?
您可以通过操纵 IFS 来影响字段分割的完成方式,但您需要这样做前您的脚本正在启动,即:
% SAVIFS="$IFS" ;导出 IFS="" % /path/to/your/script arg1 arg2 ... % IFS="$SAVIFS"
您可以根据自己的规则在脚本内进行字段拆分。为此,您捕获全部将参数放入一个字符串中,然后自己将其拆分:
/bin/bash #!/bin/bash chArgs =“$ *” arg1=“” arg1=“” [...] shopt -s 最后一管 # 在这里分割$chArgs的内容,例如: 回声“$chArgs”| IFS=''读取arg1 arg2 printf "%s\n%s\n" "$arg1" "$arg2" # 或者,只是为了展示它是如何工作的: 回声“$chArgs”| IFS=','读取arg1 arg2 printf "%s\n%s\n" "$arg1" "$arg2"
但请注意,在处理字符串时,尤其是可能包含 IFS 中的字符的字符串时,您始终需要遵守正确的引用。在你的例子中:
#!/bin/bash
var1=$1
var2=$2
echo $var1
echo $var2
缺少这个正确的引用,我想这是它没有像您期望的那样工作的一个(额外的)原因。尝试:
#!/bin/bash
var1="$1"
var2="$2"
echo "$var1"
echo "$var2"