@wanghuijiao
2021-04-01T08:55:38.000000Z
字数 5953
阅读 965
学习笔记
<something>的字串,可以替换成自己需要的值。比如可以替换成具体的文件名/tmp/1.txt出现[something]时,表示这一项是可选的、可以省略的。
$ a="value"$ echo ${a}value# 常用操作,不能省{}的情况$ cp $a ${a}_backup# 内嵌在字符串中,双引号展开变量,对变量进行解释$ echo "${a} is cool"value is cool# 单引号原样输出$ echo '${a} is cool'${a} is cool# "\"是使特殊字符保持原样,"\$"会使得"$"仅作为普通字符,"$a"不再被替换$ echo "\$a is cool"$a is cool$ echo '\$a is cool'\$a is cool
$PATH,表示搜索可执行文件的路径列表。(有点不懂,需要稍后自行查询)。用env查询当前系统里的所有内置变量。$1,$2...得到命令行输入参数,$0是脚本本身。
$ cat watch-arguments.sh#!/bin/bashecho "script file name : $0"echo "first argument : $1"echo "second argument : $2"$ ./watch-arguments.sh good jobscript file name : ./watch-arguments.shfirst argument : goodsecond argument : job
CUDA_VISIBLE_DEVICES该变量的值,来确定使用哪些GPU。
$ CUDA_VISIBLE_DEVICES='0,1' python train.py
export: 用export赋值的变量,子进程可见. 因此设置环境变量有两种方式,一种是命令前同一行直接赋值, 另一种是用export赋值. 区别是后者在本shell的生命周期内都有影响.
$ python -c 'import os; import sys;print os.environ.get(sys.argv[1])' some_var# 直接在shell中赋值的变量,子进程不可见None$ some_var=kk python -c 'import os; import sys;print os.environ.get(sys.argv[1])' some_var#直接在子进程运行前赋值的变量,是可见的.$ echo $some_var# 上一行中的单行赋值方式不会"污染"全局环境, 仅对后面接的命令有效.(输出为空)$ export some_var='kk'$ echo $some_varkk$ python -c 'import os; import sys;print os.environ.get(sys.argv[1])' some_varkk
$ echo 'k1=v1' > vars.sh$ chmod +x ./vars.sh$ ./vars.sh$ echo $k1 # 什么都没有输出来。原因是刚才 'k1=v1' 在一个独立的sh脚本运行时,会在新开的子shell中运行,子shell运行结束后,其中的变量(k1)也不复存在。因此子shell中的这句赋值不会对父shell有任何影响。$ source ./vars.sh$ echo $k1 # 这一次赋值的效果出现在了父shell中。原因是 source 后的脚本,不再是新开子shell运行,source使得 vars.sh 中的每一行,像在父shell中执行一样。本例中,就是 k1=v1 在父shell中运行了。v1
$()或``,将$()的输出结果赋值给另一个变量
$ ret=$(cat readme.txt)$ echo $retWorking in 837 is a lot of fun.$ ret=`cat readme.txt`$ echo $retWorking in 837 is a lot of fun.
$ let "a=5+6"$ echo $a11$ x=5$ y=6$ let "z=x*y"$ echo $z30
$ expr 5 + 611$ foo=$(expr 5 + 6)$ echo $foo11
$ a=$((5+6))$ echo $a11
if <condition>then<cmd>else<cmd>fi
else语句可以省略。比如:
#!/bin/bashtmp=35# -ge great or equalif [ ${tmp} -ge 30]thenecho "It's hot, we should turn on the AC."elsefi
# 其中-e用来判断文件是否存在。if [ -e /bin/ls ]thenecho "Your 'ls' binary is on the usual path."elseecho "I can't find the 'ls' binary."fi# 比较大小$ test 5 -ge 4$ echo $?0# 其中$?是上一个命令的返回结果。Test命令的返回结果,0表示结果是True或者命令运行成功;1表示结果是False或者命令运行不成功
code_review="pass"regression_test="pass"if [ $code_review = "pass" ] && [ $regression_test = "pass" ]thenecho "ship it!"fi
$ for var in <list>do<command>done# 示例$ cat test-loop.sh#!/bin/bashfor x in 830 837 846 859doecho "Our teams are in room ${x}."done
echo {1..3}for i in {1..3}doecho "I got ${i} tickets."done# 输出1 2 3I got 1 tickets.I got 2 tickets.I got 3 tickets.
for ((i=1; i<=3; i++))doecho "I fixed ${i} bugs."done# 输出I fixed 1 bugs.I fixed 2 bugs.I fixed 3 bugs.
until [ <some test> ]do<commands>done
i++ bash支持自加写法
suffix=1until [ ! -e "foo${suffix}" ]dolet suffix++doneecho "The file name foo${suffix} is good."
# 发现第一个有鱼的餐厅,打印并退出for res in YUYU LanZhouLaMian ShaoFen fishdo# -q 表示不显示,在${res}.txt文件中查找fish字符grep -q fish ${res}.txt# $?用来获取上一条命令的返回值found=$?if [ $found = 0 ]thenecho "We have fish from $res!"breakfidone
# 跳过所有含辣的餐馆for res in YUYU LanZhouLaMian ShaoFen fishdogrep -q spicy ${res}.txtfound=$?if [ $found = 0 ]thencontinuefidone
function_name (){<commands>}# 或者function function_name{<commands>}
调用时,直接调用function_name即可。必须在调用前定义函数。
# 下面的函数打印系统信息:print_distro_info() {echo "Here is the distro info:"uname -a}print_distro_info
函数也可以有参数,用\$1,$2得到,例如:
discuss_languages(){languages1=$1languages2=$2echo "$1 is a good language."echo "$2 is also a good language."}discuss_languages c++ python
注意调用时,参数两边没有括号
find_cpp_files(){local folder=$1local ret=$(find ${folder} -name '*.cpp' | wc -l)return $ret}folder=/ssd01/wanghuijiaofind_cpp_files $foldernum_files=$?echo "There are ${num_files} cpp files in ${folder}"
#!/bin/bash# Experimenting with variable scopevar_change(){local var1='local 1'echo "Inside function: var1=\"$var1\" var2=\"$var2\""var1='change again'var2='2 changed again'}var1='global 1'var2='global 2'echo "Before function call: var1=\"$var1\" var2=\"$var2\""var_changeecho "After function call: var1=\"$var\" var2=\"$var2""
#!/bin/bashset -emkdir ./tmp/dataecho "Directory ./tmp/data was just created."# 输出mkdir:./tmp/data: File exists
#!/bin/bashset -xfloor=8thecho "A lot of power has been consumed at the ${floor} floor."# 输出+ floor=8ths+ echo 'A lot of power has been consumed at the 8th floor.'A lot of power has been consumed at the 8th floor.
注意:实际调试可以用bash -x或bash -e的方式来运行脚本,来达到set -x或者set -e 的效果。这样的好处时不需要改脚本。
find . -name "*.py" | wc -lprintf '#!/bin/bash\ngrep "processor|model name" /proc/cpuinfo\n' > /tmp/1.shtouch testfile # 修改文件时间属性为当前系统时间,若testflie不存在则创建新的testfile空白文件ls -l testfile # 查看文件时间属性