Linux——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'

返回
sds
333dfdf
${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

else语句可以省略。
例如:

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来判断

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、布尔运算

运算表达式可以用布尔运算连接起来,比如&&或||
if [ $code_review = "pass" ] && [ $regression_test = "pass" ] # 注意多个表达式需要多个[]之间用布尔运算,而不是一个[]

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

while循环语句
while read jpg_file; do # 读取每一行的路径,并赋值给jpg_file变量

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

注意:实际调试可以用bash -x或者bash -e的方式运行脚本, 来达到set -x或者set -e的效果。 这样的好处是不需要改脚本。
程序开头设置如下,能够在碰到异常情况时停止执行。

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

stdoutstderr: 程序的输出包括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获取命令行参数

$1, $2, $3分别表示第一个,第二个,第三个…命令行参数,$0为bash命令本身
echo "first is $1"
获取所有的命令行参数:"$@"
echo "$@"
获取命令行参数的个数:"$#"
echo “$#”

  • 26
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值