我的 bash 脚本有什么问题?它无法指定我的 OS 类型
What's wrong with my bash script? It cannot specify my OS type
#!/bin/bash
if [ ["$OSTYPE" == "linux-gnu"*] ]; then
SCRIPT_PATH=$(dirname $(realpath -s [=12=]))
elif [ ["$OSTYPE" == "darwin"*] ]; then
SCRIPT_PATH=$(dirname $(pwd))
echo "mac!!"
else
echo "Unknown OS!"
exit
fi
我想写一个bash脚本来指定OS类型。
但是在我的MacOS上,结果显示“Unknown OS!”,这是错误的。
我在终端中尝试 echo $OSTYPE
,它显示 darwin20.0。
所以我想知道我的代码有什么问题?
问题是您试图通过 =="..."*
检查通配符表达式。这需要通过 grep
完成。尝试这样的事情:
#!/usr/bin/env bash
# define method
function checkOS() {
local os="$OSTYPE";
if [[ "$os" == "msys" ]]; then
echo "windows";
elif ( echo "$os" | grep -Eq "^darwin.*$" ); then
echo "mac";
elif ( echo "$os" | grep -Eq "^linux-gnu.*$" ); then
echo "linux";
else
echo "Unknown OS!" >> /dev/stderr;
exit 1;
fi
}
# try method
os="$( checkOS )";
echo -e "Current OS is 3[1m${os}3[0m.";
确保左括号和右括号之间没有空格,即 [[
和 ]]
与 [ [
和 ] ]
相比,您可能会去掉在你的模式中引用:
#!/usr/bin/env bash
OSTYPE=linux-gnu-123
if [[ "$OSTYPE" == linux-gnu* ]]; then
echo "linux"
elif [[ "$OSTYPE" == darwin* ]]; then
echo "mac"
else
echo "Unknown OS!"
fi
此外,使用 https://www.shellcheck.net/ 验证您的脚本。
case
语句专门用于将单个字符串与各种模式进行比较,并根据匹配的模式执行不同的操作:
#!/bin/bash
case "$OSTYPE" in
"linux-gnu"* )
script_path="$(dirname "$(realpath -s "[=10=]")")" ;;
"darwin"* )
script_path="$(dirname "$(pwd)")" ;;
* )
echo "Unknown OS!" >&2
exit 1 ;;
esac
注意:每个模式在末尾用 )
分隔。您也可以在开头放一个 (
,但大多数人不会打扰。每个案例都以双分号结尾。最后的 *
案例将匹配任何 不匹配早期模式 的内容,因此它的功能类似于 if ... elif ...
中的 else
子句声明。
我做的一些其他更改:
- 双引号变量引用和命令替换(例如
"$(realpath -s "[=17=]")"
而不仅仅是 $(realpath -s [=18=])
)是个好主意,以避免值中某些字符(主要是空格)出现奇怪的解析问题。 (有些地方可以安全地去掉双引号,但不值得去记住它们的位置。)
- 由于有一大堆具有特殊功能的全大写名称,最安全的做法是使用小写或混合大小写的名称(例如
script_path
而不是 SCRIPT_PATH
)以避免冲突。
- 错误和状态消息(如“Unknown OS!”)通常应发送到标准错误而不是标准输出。我使用
>&2
将消息重定向到标准错误。
- 当脚本(或函数、程序或其他)在错误后退出时,它应该 return 非零退出状态以指示它失败。不同的代码可以用来表示不同的问题,但是 1 通常用作通用的“出错了”代码,所以我在这里使用
exit 1
。
我建议使用 shellcheck.net 来扫描您的脚本以查找常见错误。它会为你省去很多麻烦。
#!/bin/bash
if [ ["$OSTYPE" == "linux-gnu"*] ]; then
SCRIPT_PATH=$(dirname $(realpath -s [=12=]))
elif [ ["$OSTYPE" == "darwin"*] ]; then
SCRIPT_PATH=$(dirname $(pwd))
echo "mac!!"
else
echo "Unknown OS!"
exit
fi
我想写一个bash脚本来指定OS类型。
但是在我的MacOS上,结果显示“Unknown OS!”,这是错误的。
我在终端中尝试 echo $OSTYPE
,它显示 darwin20.0。
所以我想知道我的代码有什么问题?
问题是您试图通过 =="..."*
检查通配符表达式。这需要通过 grep
完成。尝试这样的事情:
#!/usr/bin/env bash
# define method
function checkOS() {
local os="$OSTYPE";
if [[ "$os" == "msys" ]]; then
echo "windows";
elif ( echo "$os" | grep -Eq "^darwin.*$" ); then
echo "mac";
elif ( echo "$os" | grep -Eq "^linux-gnu.*$" ); then
echo "linux";
else
echo "Unknown OS!" >> /dev/stderr;
exit 1;
fi
}
# try method
os="$( checkOS )";
echo -e "Current OS is 3[1m${os}3[0m.";
确保左括号和右括号之间没有空格,即 [[
和 ]]
与 [ [
和 ] ]
相比,您可能会去掉在你的模式中引用:
#!/usr/bin/env bash
OSTYPE=linux-gnu-123
if [[ "$OSTYPE" == linux-gnu* ]]; then
echo "linux"
elif [[ "$OSTYPE" == darwin* ]]; then
echo "mac"
else
echo "Unknown OS!"
fi
此外,使用 https://www.shellcheck.net/ 验证您的脚本。
case
语句专门用于将单个字符串与各种模式进行比较,并根据匹配的模式执行不同的操作:
#!/bin/bash
case "$OSTYPE" in
"linux-gnu"* )
script_path="$(dirname "$(realpath -s "[=10=]")")" ;;
"darwin"* )
script_path="$(dirname "$(pwd)")" ;;
* )
echo "Unknown OS!" >&2
exit 1 ;;
esac
注意:每个模式在末尾用 )
分隔。您也可以在开头放一个 (
,但大多数人不会打扰。每个案例都以双分号结尾。最后的 *
案例将匹配任何 不匹配早期模式 的内容,因此它的功能类似于 if ... elif ...
中的 else
子句声明。
我做的一些其他更改:
- 双引号变量引用和命令替换(例如
"$(realpath -s "[=17=]")"
而不仅仅是$(realpath -s [=18=])
)是个好主意,以避免值中某些字符(主要是空格)出现奇怪的解析问题。 (有些地方可以安全地去掉双引号,但不值得去记住它们的位置。) - 由于有一大堆具有特殊功能的全大写名称,最安全的做法是使用小写或混合大小写的名称(例如
script_path
而不是SCRIPT_PATH
)以避免冲突。 - 错误和状态消息(如“Unknown OS!”)通常应发送到标准错误而不是标准输出。我使用
>&2
将消息重定向到标准错误。 - 当脚本(或函数、程序或其他)在错误后退出时,它应该 return 非零退出状态以指示它失败。不同的代码可以用来表示不同的问题,但是 1 通常用作通用的“出错了”代码,所以我在这里使用
exit 1
。
我建议使用 shellcheck.net 来扫描您的脚本以查找常见错误。它会为你省去很多麻烦。