我正在编写需要在Linux和Mac上运行的bash脚本。
我正在编写一个函数,根据我所处的环境返回目录路径。
这是伪代码:
如果我在Mac OS X机器上,我需要我的功能来返回路径:
/usr/local/share/
否则如果我在Linux机器上,我需要我的函数来返回路径:
/home/share/
否则,你既不在Linux上也不在Mac上......抱歉。
我对Bash很新,所以我提前为这个非常简单的问题道歉。
以下是我写的功能。无论我是在Mac还是Linux上,它总会返回
/usr/local/share/
请看看Bash的微妙之处,启发我。
function get_path(){
os_type=`uname`
if [ $os_type=="Darwin" ]; then
path="/usr/local/share/"
elif [ $os_type=="Linux" ]; then
path="/home/share/"
else
echo "${os_type} is not supported"
exit 1
fi
echo $path
}
答案 0 :(得分:2)
在测试命令中需要操作符周围的空格:[ $os_type == "Darwin" ]
而不是[ $os_type=="Darwin" ]
。实际上,您还应该使用=
而不是==
(双重等于是一种基础,并且不会在所有shell中起作用)。此外,function
关键字也是非标准关键字,您应该将其关闭。此外,您应该引用变量引用(如"$os_type"
),以防它们包含空格或任何其他有趣的字符。最后,向标准输出回显错误消息(" ...不支持")可能会混淆调用该函数的任何内容,因为它会出现在预期找到路径的位置;将其重定向到标准错误(>&2
)。以下是我清理过的内容:
get_path(){
os_type=`uname`
if [ "$os_type" = "Darwin" ]; then
path="/usr/local/share/"
elif [ "$os_type" = "Linux" ]; then
path="/home/share/"
else
echo "${os_type} is not supported" >&2
exit 1
fi
echo "$path"
}
编辑:我对作业和比较之间差异的解释对于评论来说太长了,所以我在这里添加它。在许多语言中,标准表达式语法在独立使用时与测试中相同。例如,在C a = b
中,无论是单独行还是像if ( a = b )
这样的上下文,都会做同样的事情。 shell不是那样的 - 它的语法和语义根据确切的上下文而变化很大,它是确定含义的上下文(不是等号的数量)。以下是一些例子:
a=b
本身就是一项作业a = b
本身将a
作为命令运行,并将参数传递给#34; ="和" b"。[ a = b ]
使用参数" a"," =&#34运行[
命令(这是test
命令的同义词) ;," b"和"]" - 它忽略"]",并将其他人解析为比较表达式。[ a=b ]
也会运行[
(test
)命令,但这次删除"]"它只能看到一个参数," a = b" - 当test
给出一个参数时,如果参数不是空白,则返回true,这个参数不是。 bash的内置版[
(test
)接受==
作为=
的同义词,但并非所有其他版本都这样做。
[[ ]]
个表达式(如test
,但更清晰,更强大)和(( ))
表达式(与其他所有内容完全不同) ,甚至( )
(将其内容作为命令运行,但在子shell中)。
答案 1 :(得分:1)
您需要了解[
的含义。最初,这是/bin/test
命令的同义词。这些是相同的:
if test -z "$foo"
then
echo "String '$foo' is null."
fi
if [ -z "$foo" ]
then
echo "String '$foo' is null."
fi
现在,您可以看到为什么所有参数都需要空格。这些是参数而不仅仅是布尔表达式。实际上,test联机帮助页是了解各种测试的好地方。 (注意:test
和[
是在BASH shell的命令中构建的。)
if [ $os_type=="Darwin" ]
then
这应该是三个参数:
"$os_type"
=
而非==
"Darwin"
if [“$ os_type”=“Darwin”]#[
命令的三个参数
然后
如果使用单方括号,则应习惯用引号括住参数。否则,你会遇到麻烦:
foo="The value of FOO"
bar="The value of BAR"
if [ $foo != $bar ] #This won't work
then
...
在上面,shell会在评估表达式之前插入$foo
和$bar
及其值。你会得到:
if [ The value of FOO != The value of BAR ]
[
会看到这一点并意识到The
或value
都不是正确的参数,并会抱怨。使用引号可以防止这种情况:
if [ "$foo" != "$bar" ] #This will work
then
这变为:
if [ "The value of FOO" != "The value of BAR" ]
这就是为什么强烈建议您为测试使用双方括号:[[ ... ]]
。测试在shell插入之前查看参数:
if [[ $foo = $bar ]] #This will work even without quotation marks
此外,[[ ... ]]
允许模式匹配:
if [[ $os_type = D* ]] # Single equals is supported
then
path="/usr/local/share/"
elif [[ $os_type == L* ]] # Double equals is also supported
then
path="/home/share/"
else
echo "${os_type} is not supported"
exit 1
fi
这样,如果字符串为Darwin32
或Darwin64
,则if
语句仍然有效。再次注意,所有东西都必须有空格,因为这些是命令的参数(实际上,不再是,但这就是shell解析它们的方式)。
答案 2 :(得分:0)
在条件的参数之间添加空格来解决问题。
这有效
function get_path(){
os_type=`uname`
if [ $os_type == "Darwin" ]; then
path="/usr/local/share/"
elif [ $os_type == "Linux" ]; then
path="/home/share/"
else
echo "${os_type} is not supported"
exit 1
fi
echo $path
}