[foo bar oni =“ foo bar oni”]
由于环境变量未用双引号引起来,因此bash认为方括号中的参数过多. 您可以使用双引号将字符串参数括起来以消除此问题. 请记住,如果您习惯于将所有字符串参数都用双引号引起来,则会消除许多类似的编程错误. “ foobar oni”的比较应写为:
if [“ $ myvar” =“ foo bar oni”]
然后
回声“是”
fi
在调用环境变量时,最好使用“”将环境变量括起来. (注意: 如果要引用环境变量的值,请不要使用单引号,因为单引号将禁用变量(和历史记录)扩展. 如上例所示,仅接受空格前的字符)
圆形结构: “用于”
好的,让我们开始for循环: )首先让我们看一个简单的示例:
#! / bin / bash
一进二出三进四出
做
回声数$ x
完成
输出:
第一名
第二名
第三名
第四个
在此示例中,“ forx”部分定义了一个名为“ $ x”的新环境变量(也称为循环控制变量),其值设置为“ one”,“ two”和“ three”,并且“四个”. 每次分配后,将执行循环体(“ do”和“ done”之间的代码). 在循环主体中,与其他环境变量一样,标准变量扩展语法用于引用循环控制变量“ $ x”. 另请注意,“ for”循环始终在“ in”语句之后接受某种类型的单词列表. 在此示例中,指定了四个英文字母,但是单词列表也可以引用磁盘上的文件,甚至文件通配符. 让我们看一下使用标准外壳通配符的另一个示例:
#! / bin / bash
对于/ etc / r中的myfile *
做
如果[-d“ $ myfile”]
然后
回显“ $ myfile(dir)”
其他
回显“ $ myfile”
fi
完成
输出:

/etc/rc.d(dir)
/etc/resolv.conf
/etc/resolv.conf~
/ etc / rpc
上面的代码列出了/ etc中以“ r”开头的每个文件. 为此,bash首先在执行循环之前获取通配符/ etc / r *,然后使用字符串/ etc / rc对其进行扩展.d /etc/resolv.conf/etc/resolv.conf~ / etc / rpc替换. (也就是说,将循环语句替换为/etc/rc.d/etc/resolv.conf /etc/resolv.conf~ / etc / rpc中的myfile). 根据myfile是否为目录,进入循环, “ -d”条件运算符用于执行两个不同的操作. 如果是目录,请在输出行后附加“(dir)”.
您还可以在单词列表中使用多个通配符甚至环境变量:
对于x in / etc / r--? / var / lo * / home / drobbins / mystuff / * / tmp / $ {MYPATH} / *
做
cp $ x / mnt / mydir
完成
尽管所有通配符扩展示例都使用绝对路径,但也可以使用相对路径,如下所示:
对于../* mystuff / *
中的x
做
echo $ x是asilly文件
完成
再看一个例子:
对于x in / var / log / *
做
echo`basename $ x`是/ var / log目录中的文件
完成
看看如何使用“ $ @”:
#! / usr / bin / env bash
针对“ $ @”中的内容
做
您输入的是$ {thing}.
完成
输出:
$ allargs你好,你在那里
您打了招呼.
您在那打过字.
您键入了您
您打傻.
壳算术
在学习另一种类型的循环结构之前,最好先熟悉如何执行Shell算术. 您可以使用Shell结构执行简单的整数运算. 只需将某些算术表达式包含在“ $((“和”))”中,bash即可计算该表达式. 以下是一些示例:
$ echo $((100/3))
33
$ myvar =“ 56”
$ echo $((($ myvar + 12))
68
$ echo $((($ myvar- $ myvar))
0 $ myvar = $((($ myvar + 1))
$ echo $ myvar
57
更多循环结构: “ while”和“ until”
只要满足特定条件,“ while”语句将以以下格式执行:
同时[条件]
做
声明
完成
通常使用“ While”语句循环一定次数,例如,以下示例将循环10次:
myvar = 0
同时[$ myvar -ne 10]
做
echo $ myvar
myvar = $((($ myvar + 1))
完成
如您所见,上面的示例使用算术表达式使条件最终为false并导致循环终止.
“ Until”语句提供与“ while”语句相反的功能: 只要某些条件为假,它们就会重复. 这是一个“ until”循环,其功能与先前的“ while”循环相同:
myvar = 0
直到[$ myvar -eq 10]
做
echo $ myvar
myvar = $((($ myvar + 1))
完成
案例陈述
case语句是另一个方便的条件结构. 这是一个示例片段:

在
的情况下为“ $ {x ## *. }”
gz)
gzunpack $ {SROOT} / $ {x}
;;
bz2)
bz2unpack $ {SROOT} / $ {x}
;;
*)
回声“无法识别存档格式. ”
退出
;;
esac
在上面的示例中,bash首先扩展“ $ {x ## *. }”. 在代码中,“ $ x”是文件的名称,而“ $ {x ##. *}”将删除文件中最后一个句点之后的文本以外的所有文本. 然后,bash将结果字符串与“)”左侧列出的值进行比较. 在此示例中,首先将“ $ {x ##. *}”与“ gz”进行比较,然后与“ bz2”进行比较,最后与“ *”进行比较. 如果“ $ {x ##. *}”匹配这些字符串或模式中的任何一个,则执行紧跟在“)”之后的行直到“ ;;”,然后bash在该行的终止符“ esac”之后继续执行. 如果它不匹配任何模式或字符串,则不执行任何代码行. 在此特定代码段中,至少必须执行一个代码块,因为任何不匹配“ gz”或“ bz2”的字符串都将匹配“ *”模式匹配.
函数和名称空间
您还可以在bash中定义函数. 函数甚至可以以类似于脚本接受命令行参数的方式接受参数.
tarview(){
echo -n“显示$ 1的内容”
如果[$ {1 ## *. } =焦油]
然后
回显“(未压缩的tar)”
tar tvf $ 1
elif [$ {1 ## *. } = gz]
然后
回显“(gzip压缩的tar)”
tar tzvf $ 1
elif [$ {1 ## *. } = bz2]
然后
回显“(bzip2压缩的tar)”
cat $ 1 | bzip2 -d | tar tvf-
fi
}
(echo -n不换行)
上面定义了一个名为“ tarview”的函数,该函数接收一个参数,这是某种类型的tar文件. 执行该函数时,它将确定参数是哪种tar文件类型(未压缩,gzip压缩或bzip2压缩),打印一行信息性消息,然后显示tar文件的内容.
$ tarview Short.tar.gz
显示short.tar.gz(gzip压缩的tar)的内容
drwxr-xr-x ajr /方丈0 1999-02-2716: 17缩短2.3a /
-rw-r--r-- ajr / abbot 11431997-09-04 04:06 short-2.3a / Makefile
-rw-r--r-- ajr / abbot 11991996-02-04 12:24 short-2.3a /安装
-rw-r--r-- ajr / abbot 8391996-05-29 00:19 short-2.3a /许可
....
命名空间
通常需要在函数中创建环境变量. 尽管有可能,但应了解一个技术细节. 在大多数编译语言(例如C)中,当在函数内部创建变量时,该变量将放置在单独的本地名称空间中. 因此,如果在C中定义了名为myfunction的函数,并且在函数中定义了名为“ x”的自变量,则不会影响任何名为“ x”的全局变量(函数以外的变量). 它具有消除负数的印象. 效果.
这在C语言中是正确的,但在bash中却不是. 在bash中,每当在函数内部创建环境变量时,都会将其添加到全局名称空间中. 这意味着该变量将覆盖函数外部的全局变量,并在函数退出后继续存在:
#! / usr / bin / env bash
myvar =“你好”
myfunc(){
myvar =“一二三”
对于$ myvar中的x
做
回声$ x
完成
}
myfunc
echo $ myvar $ x
运行此脚本时,它将输出“一二三三”,这表明函数中定义的“ $ myvar”如何影响全局变量“ $ myvar”,以及循环控制变量“ $ x”如何退出. 该函数此后将继续存在(如果存在“ $ x”全局变量,它也会受到影响).
在这个简单的示例中,使用其他变量名很容易找到错误并更正错误. 但这不是正确的方法,解决此问题的最佳方法是通过使用“ local”命令从一开始就防止影响全局变量的可能性. 使用“本地”在函数内部创建变量时,它们将放置在本地名称空间中,并且不会影响任何全局变量. 这里演示了如何实现上述代码,以免重写全局变量:
#! / usr / bin / env bash
myvar =“你好”
myfunc(){
本地x
localmyvar =“一二三”
对于$ myvar中的x
做
回声$ x
完成
}
myfunc
echo $ myvar $ x
此函数将输出“ hello”-全局变量“ $ myvar”不会被重写,并且“ $ x”在myfunc之外不存在. 在函数的第一行中,我们创建了局部变量x以供以后使用,在第二个示例中(local myvar =“ one two three”“),我们创建了局部变量myvar并为其分配了值. 在将循环控制变量定义为局部变量时,使用第一种形式很方便,因为不允许这样说: “ $ myvar中的forlocal x. ”此函数不影响任何全局变量,建议您这样做. 以这种方式设计所有函数. 仅在明确要修改全局变量的情况下,才应使用“ local”. 创建局部环境变量时最好使用“ local”.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-198627-2.html
濒海战斗舰也就是反恐和特种作战用的
我们真的倒退100年