Bash 将函数参数识别为程序

Bash 将函数参数识别为程序

我对 bash 的语法还不太熟悉,我的 '.bash_aliases' 文件中有一段代码。它要么获取一个整数作为参数,要么获取字母 'c',当它获取一个整数时,它会将该整数放入环境变量中,Web 服务器可以将其用作端口。当它获取字母 'c' 作为输入时,它会清除该变量。

当我尝试使用整数运行命令时出现错误

main@linuxWSL:~$ serverp 2000
-bash: [: missing `]'
2000: command not found

当我用字母“c”尝试时,我得到了

main@linuxWSL:~$ serverp c
-bash: [: missing `]'
c: command not found

这是我的 bash 代码:

serverp () {
  if [ "$1" = "clear" || "$1" = "c" ]
  then
    unset PORT
    echo -e "\e$CLEAR$GREEN""mWebServer port has been reset!""$CLEAN"
    return 0
  fi

  export PORT="$1"
}

有人能帮帮我吗?谢谢!

答案1

[不是 Bash 中的关键字,它不会使 shell 解析器以不同的方式解释其余命令行。[是一个类似cat或的命令echo[(类似echo)是 Bash 中的内置命令,但这仅意味着它可以在不产生额外进程的情况下运行,它仍然表现得像一个命令。

需要明确的是:[ … ]不是语法的一部分if … then …if只是测试某些代码的退出状态:if true; then …有效,if sleep 5; then …有效,同样if [ … ]; then …有效(如果该[ … ]部分本身是一个有效命令)。

[您的系统中可能有可执行文件。尝试type -a [。与 进行比较type -a [[。与 相对[[[是 Bash 中的一个关键字,它确实使解析器特殊处理[[和之间的内容]]

[不是关键字。正确的写法是,只有最后一个参数[ … ]是命令。需要作为最后一个参数,否则它将无法工作。这只是为了使它作为一个块突出,就好像它是某种特殊语法一样;但它不是一种特殊语法。][][ … ]

[ "$1" = "clear" || "$1" = "c" ]shell 会将你的命令解释为[ "$1" = "clear"并与"$1" = "c" ]连接||。因此有两个命令。第一个命令是[ "$1" = "clear"[被执行,但它没有获得]最后一个参数,它会报错并以非零退出状态退出。由于非零状态和||,shell 会尝试运行第二个命令,该命令以扩展为 开头"$1"。这样,你的脚本的第一个参数将被解释为要运行的可执行文件。

[ … || … ]像这样修复你:

[ "$1" = "clear" ] || [ "$1" = "c" ]

此代码片段包含两个有效的 [命令。它应该会执行您想要的操作。

注意[[ "$1" = "clear" || "$1" = "c" ]]是一段可运行的代码,而[ "$1" = "clear" || "$1" = "c" ]不是。这是因为[[不是命令。它是一个关键字,它使 shell 解析器将所有内容]]特殊处理;这包括||。还有其他[[和之间的差异[,不要盲目地互换它们。

[Bash 内置命令-o支持或者-a以及),因此下面这个也可以:

[ "$1" = "clear" -o "$1" = "c" ]

您的代码中,将||(特定于 shell) 替换为-o(不特定于 shell)。-o但您应该避免这样做。从本文

二进制-a-o[…] 是 POSIX 标准的 XSI 扩展。在 POSIX-2008 中,它们都被标记为过时。它们不应在新代码中使用。[ A = B -a C = D ](or ) 的一个实际问题是 POSIX 不指定带有超过 4 个参数的or命令-o的结果。它可能在大多数 shell 中都有效,但您不能指望它。如果您必须为 POSIX shell 编写,那么您应该使用由运算符分隔的两个or命令。test[test[&&

请注意,本文详细阐述了-a,因此“&&改为使用运算符”。在您的例子中,分别是-o||。用运算符分隔的两个测试||正是我们的解决方案。

答案2

它是if [ "$1" = "clear" ] || [ "$1" = "c" ]

相关内容