bash脚本:如果参数等于此字符串,则定义一个类似于此字符串的变量


225

我正在做一些bash脚本,现在我得到了一个变量调用source和一个数组samples,如下所示:

source='country'
samples=(US Canada Mexico...)

当我想扩展源的数量(每个源都有自己的样本)时,我尝试添加一些参数来执行此操作。我尝试了这个:

source=""
samples=("")
if [ $1="country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
   echo "try again"
fi

但是当我运行脚本时,source countries.sh country它不起作用。我究竟做错了什么?


2
它怎么不起作用?当您运行它时,您会得到一个错误,或者说“重试”,或者其他什么?
邪恶otto

2
是的,您可能会认为“问题非常简单”。但您已经考虑了一段时间。请考虑编辑您的问题以包括必需的输出和您收到的任何错误消息。+1,用于实际尝试操作和问题的良好格式。祝好运。
剥壳机2012年

为什么此代码与提议并接受的解决方案相同?这很令人困惑...我猜想最初的问题在if语句的右括号和右括号之前没有空格吗?
Stef

6
@Stef,如果您仔细观察,则$1="country"$1 = "country"

Answers:


413

不要忘记空格:

source=""
samples=("")
if [ $1 = "country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
  echo "try again"
fi

121
我不能相信,我花费在这三个小时,并且是唯一的空间问题!!!! ...谢谢@Alex
亚历杭德罗·

1
为什么samples="US Canada Mexico..."在介绍完数组创建之后再使用samples=(US Canada Mexico...)
用户未知

10
当左边的变量是一个空字符串时,我遇到了这个问题。解决方法是if [ "$1" = "country" ]; then
安德鲁布(Andrewb)2015年

8
好的,就是这样。Bash正式成为蜜蜂最陈旧但仍使用的命令语言的投票人。语法太不直观,很痛苦。在2016年以后真的没有地方了。@Systemd作者:您能否请下一个项目“构建一个不会吸引人的Linux shell”?我会向你扔钱。
masi

3
@masi有时我认为Unix的初衷是“通过默默无闻来确保工作安全”。如果这些工具使用起来很神秘,难以理解,而且如果没有将内部知识从大师传授给Padwan的话,通常这些工具是无法洗净的,那将确保那些“知道的人”总能找到工作。这种理念在整个“ RFC”结构和手册文档中使用的华丽语言中很明显,尽管在技术上告诉您如何使用工具,但实际上只是为了满足对工具进行文档化的要求。几乎没有改变。
不同步的

184

您可以使用“ =”或“ ==”运算符在bash中进行字符串比较。重要的因素是括号内的间距。正确的方法是使方括号内包含空格,而运算符之间包含空格。在某些情况下,不同的组合起作用。但是,以下旨在作为通用示例。

if [ "$1" == "something" ]; then     ## GOOD

if [ "$1" = "something" ]; then      ## GOOD

if [ "$1"="something" ]; then        ## BAD (operator spacing)

if ["$1" == "something"]; then       ## BAD (bracket spacing)

另外,请注意,与使用单括号相比,双括号的处理方式略有不同...

if [[ $a == z* ]]; then   # True if $a starts with a "z" (pattern matching).
if [[ $a == "z*" ]]; then # True if $a is equal to z* (literal matching).

if [ $a == z* ]; then     # File globbing and word splitting take place.
if [ "$a" == "z*" ]; then # True if $a is equal to z* (literal matching).

希望对您有所帮助!


12

看来您正在寻找将命令行参数解析为bash脚本的方法。我最近自己搜索了这个。我遇到了以下问题,我认为这将有助于您解析参数:

http://rsalveti.wordpress.com/2007/04/03/bash-parsing-arguments-with-getopts/

我将以下代码段添加为tl; dr

#using : after a switch variable means it requires some input (ie, t: requires something after t to validate while h requires nothing.
while getopts ht:r:p:v OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         t)
             TEST=$OPTARG
             ;;
         r)
             SERVER=$OPTARG
             ;;
         p)
             PASSWD=$OPTARG
             ;;
         v)
             VERBOSE=1
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z $TEST ]] || [[ -z $SERVER ]] || [[ -z $PASSWD ]]
then
     usage
     exit 1
fi

./script.sh -t测试-r服务器-p密码-v

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.