大家好,欢迎来到IT知识分享网。
bash命令
一、Bash相关
1、运行Bash
(1)可以直接在命令行中运行,例如cd \xxx
(2)存储在脚本文件中执行,扩展名为.sh或者没有扩展名。
如果是用脚本文件运行:第一行写上#!/bin/bash;其中#!也叫做Shebang,另外还需要把该.sh文件设置为可执行文件。chmod +x
在计算领域中,Shebang是一个由井号和叹号构成的字符序列#!,其出现在文本文件的第一行的前两个字符。 在文件中存在Shebang的情况下,类Unix操作系统的程序加载器会分析Shebang后的内容,将这些内容作为解释器指令,并调用该指令,并将载有Shebang的文件路径作为该解释器的参数。
(3)bash脚本开头经常会有set -x参数,表示当有语句执行错误时,整个脚本能够停下来,而set -x命令表示在调试Bash脚本时,希望能够被执行的具体命令,而不仅仅是输出,因此常用set -xe
(4)bash命令行Terminal撤销输入 Ctrl+Shift±
2、变量
<variable>="value"
例如:des="sd"注意=两边不能有空格!!
读取变量使用${variable}
例如:echo ${des}
如果读取的变量后面不是分隔符(回车),那么必须使用{}
例如:cp $filename ${des}_backup否则系统会任务des_backup是一个变量
Bash中的单引号和双引号都表示字符串,但是双引号中的变量会展开,单引号不会。
例如:
s1='sds' echo ${s1} s2="333" echo "${s2}dfdf" echo '${s2}dfdf'
3、内置变量
系统一些内置变量,例如$PATH 表示搜索可执行文件的路径列表
4、环境变量
运行python train.py时会给进程设置环境变量CUDA_VISIBLE_DEVICES。
此时python train.py只能看到0,1两块GPU,不能使用其他的GPU。
普通变量的赋值和export有什么区别?
直接在Shell中赋值的变量,子进程不可见,而用export赋值的变量,子进程可见。
或者在同一行先写变量赋值,在执行子进程,例如:some_var=kk python -c 'import os; import sys;print os.environ.get(sys.argv[1])' some_var,这样子进程是可见的,而在下一个命令中是没有该变量的。
export some_var='kk' python -c 'import os; import sys;print os.environ.get(sys.argv[1])' some_var # 这样整个本Shell周期内都是可见的。
5、source
source ./vars.sh
source后的脚本不再是新开的子shell运行,source使得vars.sh中的每一行,都像是在父Shell中执行一样。
6、输出赋值
可以用 ( c o m m a n d ) 把某个命令的输出赋值给某个变量例如: ‘ v a r 1 = (command)把某个命令的输出赋值给某个变量 例如:`var1= (command)把某个命令的输出赋值给某个变量例如:‘var1=(echo “sdsdsd”)`
7、运算let expr 双括号
let "a = 5+19"
echo a返回24
let "b = 13*14"
expr会把表达式的结果输出,比如:
expr 5 * 19 !!!注意必须有空格才能当作表达式,否则就跟字符串一样的。
foo=$(expr 5 + 8) !! 注意*号貌似会返回当前目录的所有文件和文件夹,+号是可以的,但是需要有空格。
双括号。
8、if判断语句
if <condition> then <cmd> else <cmd> fi
if [ ${temp} -ge 30] # -ge的意思是大于等于greate or equ。注意-ge前面只能有一个表达式,不能${a} + ${b} -ge 3 then echo "sadsad" fi
【注意这里的if内部语句前后必须有空格。】
if [ -e /bin/ls ] # 判断文件是否存在 then echo "oko" fi
test 5 -ge 4 # echo $? # $?是上一个语句的返回结果,是上一个语句!如果上一个语句报错了,那么返回值会被更新成错误的
test 5 -ge 2 && echo "Condition is true" || echo "Condition is false",test命令常用于条件测试,其结果不会被直接输出,需要用逻辑判断来检查返回值
如果有多重判断,中间需要使用elif而不是else!!!,Bash的if语句可以嵌套
if判断是否存在某个文件夹
if [ ! -d "$output_folder" ] # 如果不存在该文件夹
9、布尔运算
10、for循环语句 for do done,while循环语句
for x in 1 2 3 44 5 do echo ${x} # 不要忘了$ done
对于数字1-n的循环,Bash有一个内置的写法{1…n}
for i in {
1...3} do echo $i done
也有类似C语言中for循环的写法:
for((i=1; i<3; i++)) do echo $i done
注意可以遍历一个字符串,以空格分隔每个字符串,这个很重要
checkpoint_path="checkpoints" checkpoint_name="aaa bbb ccc ddd eee fff" datasets_name="COCO" for ckpt in ${checkpoint_name}; do echo -ne "${ckpt}:\t" >> ${log_name} # 追加而不覆盖 for dataset in ${datasets_name}; do bash /mnt/abs.sh "/mnt/${dataset}/cost.result" >> ${log_name} done echo "" >> ${log_name} done
11、until语句 until do done
until [ ! -e "foo${suffix}" ] # 直到不存在该文件名 do let suffix++ done
12、break、continue
在循环过程中可以中途退出,或者立刻运行下一次循环。
13、函数
必须在调用前定义函数
function_name() {
# 注意这里的函数名后面一定要有() <command> } # 或者 function function_name {
<commands> }
在函数里,可以用return返回结果。Shell函数的返回值只能是介于0-255之间的整数。
find_cpp_files() {
local folder="/home/tieshuai.song/" local ret=$(find ${
folder} -name "*.stdout" | wc -l) echo $ret return $ret } find_cpp_files # 这里的调用函数不需要有() echo $? # 返回上一步的计算结果
14、scope全局变量
var_change () {
local var1='local 1' echo "Inside function : var1=\"$var1\" var2=\"$var2\"" var1='changed again' var2='2 changed again' }
15、调试技巧set
set -x # 用于启用脚本的调试模型,会使得脚本执行时将每个要执行的命令显示出来 set -e # 命令执行不成功(返回值非0)会中断,停止运行 set -u # 使用未定义的变量中断 set -o pipefail # 一个管道复合命令,只要有其中一个fail,整个命令就算fail
16、Bash随机数相关
使用$RANDOM变量以及取余运算符%来限制范围
random_number=$((1 + $RANDOM % 100)) # 这里如果直接用random_number=RANDOM % 100,bash会将其解释为字符串赋值,而不是取余操作,正确的操作是执行$((...))来进行算术运算。
17、Bash算术运算
Bash脚本中使用 $((...))来进行算术运算,使用-eq来表示等于
例如下面打印1-100以内的素数
#!/bin/bash isPrime=1 for((i=2; i<=100; i++)) do # if Prime? for((j=2; j*j<=i; j++)) do if [ $((i % j)) -eq 0 ]; then # isPrime isPrime=0 break; fi done if [ $isPrime -eq 0 ]; then isPrime=1 continue else echo $i fi done
二、Bash基础知识
1、echo:
echo "dsd" 把参数输出到屏幕,并且有回车,这点跟printf不一样,printf "sd" 输出最后没有回车
也就是echo默认会输出一个new line,而printf不会
echo sdsd也可
echo -e中-e选项是用来激活echo命令的转义字符(以\开头的例如\n换行)功能,这个很重要
echo 1111 >> a_file将1111写入文件a_file中,如果不存在就创建这个文件
echo默认是带回车的,如果不希望有回车,使用echo -n abccd类似的-n命令
2、printf
printf "sdsd” 最后没有回车
printf sdssd也是
printf和C语言中的printf类似,格式化输出
printf "i and you %d\n" 33
3、stdout和stderr
stdout和stderr: 程序的输出包括stdout和stderr,默认都会输出到终端屏幕上
echo “sds” > /tmp/ls.stdout可以把stdout输出到文件里面,内容为sds # 单个>
ls > /tmp/ls.stdout把ls返回的内容输出到终端上
ls 1> /tmp/ls.stdout 2> /tmp/ls.stderr # stdout输出到ls.stdout,stderr输出搭配ls.stderr ls &> /tmp/ls.stdall # 都保存到同一文件 rev把输入颠倒输出 ```bash rev # 先输入rev然后回车,输入👇 rev echo "sdssdsdddddd" # 按回车后返回"ddddddsdssds" ohce ver # 但是此时程序并没有结束,人工按Ctrl+D结束输入,再按一次会退出命令行
4、| && || bash组合命令
|
echo yitutech | rev会把多个命令组合起来,前一个命令的输出会变成后一个命令的输入,返回hcetutiy,一定要和||区分开
&&
程序依次执行命令,如果前一个命令报错(返回值不为0)则不执行后续的命令,echo "sds" && ls
||
前一个命令不成功,则后一个才会执行
$() 命令嵌入,可以把某一命令的输出赋给某一变量
把某个命令的输出嵌入到另一个命令中,例如echo $(seq 1 3)返回 1 2 3。【】seq 1 3是产生1-3的序列
checkpoint_name=$(find ${
checkpoint_path} -type f -name "*embed*" | grep -oP '([^\/]*)\.[^\/]*$' | sed 's/\..*//' | sort | xargs)
() 把多个命令的输出统一到某文件
当()内部多个命令,可以统一管理这些命令的输出 (echo sdsd ; ls; echo "ecccccc") > output.txt不同命令之间用;分隔
5、Bash获取命令行参数
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120953.html