Linux学习——shell

Linux

shell 语法

转义字符

\ :\后面的一个字符按照其字面意思解释
“ ”:双引号中的内容除$、`、“之外的任何字符的字面解释
‘ ’ :单引号中除 ' 以外的任何字符按其字面解释

shell变量

环境变量:标准变量,通常由管理员定义,用来保存系统必需内容
局部变量:由用户定义和控制 export 使变量变成环境变量(全局变量)

set 命令:查看当前使用的shell变量

变量赋值

shell的变量都是字符串

var1="string"
var2='string'
var3=string
#也可以使用read输入赋值
read var
read -p "please enter a number:" num

使用变量

使用$f符号
echo $var
echo ${var} // {}可以用来替换变量

  • 只读变量 readonly
    var1=name
    readonly var1
    或者 declear -r var1
  • 获取字符串长度 echo $
  • 获取子串 echo ${var:l:r} //获取从l到r区间的子串
  • 注意,当变量名字与其他变量有重复部分,最好加上

删除变量

使用unset
unset var
删除后变量变成空字符串

特殊变量

\(# 传入的参数个数 \)* 所有参数
$@ 所有参数

\[ 当前进程id $1-9 传入的参数 set 可以改变传入的参数 var1="one two three" set 'echo var1' ### 注释 ```shell # 这是单行注释 :<<EOF 这是多行注释 EOF 其中EOF可以换成其他字符串,但是前后必须一样 :<<xyz 这是多行注释 xyz ``` ### 数组 数组用小括号表示,元素之间用空格分开 array=(a b c d) 也可以直接用下标更改元素值 array[0]=1 ${array[i]} 读取数组元素 ${array[@]}读取整个数组 ${array[\*]}读取整个数组 ${#array[@]}获取数组长度 ### 判断语句 * if else语句 ```shell if condition then ... elif then else ... fi ``` * case 语句 ```shell case $var in 值1) ... ... ;; #两个;;相当于break 值2) ... ... ;; *) #相当于default ... ... ;; esac ``` * 在shell中,不能直接用=,<,>等比较整数,因为实际上这些变量是字符串,而应该使用: * -eq : == * -ne : != * -gt : > * -ge : >= * -lt : < * -le : <= ### 循环语句 * for in do done ```shell for i in val1 val2 val3 do thing1 thing2 done ``` 也可以使用命令的输出作为循环范围 ```shell for i in `ls` do echo $i done ``` 也可以指定循环范围为连续的区间,用seq命令 ```shell for i int $(seq 1 10) #输出1-10 do echo $i done ``` 或者也可以这样写 ```shell for i in {1..10} #字母也可以是{a..z} do echo $i done ``` * for((..;..;..)) do done 类似于c语言的循环 ```shell for ((i=1;i<=10;i++)) do echo $i done ``` * while do done ```shell while condition do thing1 thing2 done ``` * until do done 当条件为真时结束循环 ```shell until condition do thing done ``` eg.不断循环直到用户输入yes ```shell until [ "${word}" == "yes" ] || [ "${word}" == "YES" ] do read -p "Please input yes/YES to stop this program: " word done ``` * break break语句可以跳出当前一层循环 但是不能跳出case case 用;;来退出 ```shell while read name #这个循环直到输入EOF,即ctrl+D时结束 do for ((i=1;i<=10;i++)) do case $i in 8) break ;; *) echo $i ;; esac done done ``` * continue 跳过此次循环 ```shell for ((i=1;i<=10;i++)) do if [ `expr $i % 2` -eq 0 ] then continue fi echo $i done ``` ### 标准输入输出 * `read`可以用于标准输入 * `echo`用于标准输出 read 后可以加参数: * `-p` 后面接提示信息,相当于Python中input("Please enter balabala...") * `t` 后面接时间,规定输入的等待时间,超过了就会跳过 ### 逻辑判断与test 逻辑判断的返回值为0表示真,非零表示假 * && : `expr1 && expr2` * || : `expr1 || expr2` * test: * 数值判断: test 2 -lt 3 - | -eq | == | | ---- | ---- | | -ne | != | | -gt | > | | -lt | < | | -ge | >= | | -le | <= | * 字符串判断: * | -z | 是否为空 | | ------------- | -------- | | -n | 非空 | | str1 == str2 | == | | str1 ! = str2 | != | * 文件判断 * | -e | 存在 | | ---- | ------ | | -f | 文件 | | -d | 目录 | | -r | 可读 | | -w | 可写 | | -x | 可执行 | | -s | 非空 | * \[ \] :与test等效 ### exit * `exit`命令用来退出当前shell进程,并返回一个退出状态;使用`$?`可以接收这个退出状态。 * `exit`命令可以接受一个整数值作为参数,代表退出状态。如果不指定,默认状态值是`0`。 * `exit`退出状态只能是一个介于 `0~255` 之间的整数,其中只有 `0` 表示成功,其它值都表示失败。 ### 函数 #### 返回值与stdout 与c/c++中函数不同的是,shell中的函数返回时是`exit code` 其中code的取值是0-255, 0表示正常结束 函数的`exit code`值用`$?`获取 不写`return`默认返回0 ```shell [function] func_name() { # function关键字可以省略 code1 code2 return exit code } ``` 获取函数的stdout直接用$(函数名) output=$(func) 这样函数运行之后得到的结果不会显示到标准输出设备上,而是存储到output这个变量中 #### 函数的参数 shell函数中的参数与脚本的参数一样,都是$1-9 但是$0仍然是文件名,而不是函数名 声明函数时括号内无需写参数 ```shell func() { # 递归计算 $1 + ($1 - 1) + ($1 - 2) + ... + 0 word="" while [ "${word}" != 'y' ] && [ "${word}" != 'n' ] do read -p "要进入func($1)函数吗?请输入y/n:" word done if [ "$word" == 'n' ] then echo 0 return 0 fi if [ $1 -le 0 ] then echo 0 return 0 fi sum=$(func $(expr $1 - 1)) echo $(expr $sum + $1) } echo $(func 10) #与使用脚本的变量一样,直接在函数名字后面加上参数即可 ``` #### 函数的局部变量 用local 声明一个函数的局部变量 该变量只在函数内部有效 ```shell func(){ local var="123" echo $var } func echo $var ``` 输出结果为 ``` 123 #一行空行,表明在函数外这个局部变量不存在 ``` *** ## ssh * 用于登录远程服务器 ### ssh登录 格式: ``` ssh user@hostname -p 端口号(默认端口号22) ``` ### 配置文件 创建文件`~/.ssh/config` 在文件中输入: ``` Host myserver1 HostName IP地址或域名 User 用户名 Host myserver2 HostName IP地址或域名 User 用户名 ``` 此后登录服务器可以直接用别名`myserver1`、`myserver2` ### 密钥登录 免密登录 创建密钥 `ssh-keygen` 此后,`~/.ssh/`下会多出两个文件 * `id_rsa`:私钥 * `id_rsa.pub`:公钥 若想免密登录某个远程服务器,就复制公钥中的内容,到*远程服务器 *的`/~/.ssh/authorized_keys`文件里 也可以使用如下命令一键添加公钥 ```shell ssh-copy-id myserver ``` ### scp * 用于传输文件 ```shell scp source1 source2... destination ``` 将source下的文件复制到destination 复制文件夹: ```shell scp -r 本地文件路径 myserver:PATH ``` 将服务器的文件夹复制到本地当前路径 ```shell scp -r myserver:PATH . #注意这里有个"." 表示当前路径 ``` ## 常见命令 ### cut -f 显示指定域 -f 1-5 显示1-5域 -c 显示字符位置 -c num1-num2 -d 指定分隔符 ### paste 用于链接多个文件的域 -d 指定域 ### alias alias name='指令' 将指令改个名字 ### grep 显示指定文件中包含与指定样式匹配的行 -c 只显示包含匹配样式的行 -i 忽略大小写 -l 显示有匹配行的文件名 -n 输出前显示行号 -v 显示不匹配的行 -w 查指定字 grep 81$ 文件名 寻找81结尾的 或者可以写成 grep 81\> grep "\<王" 寻找姓王的人 ### tee 显示命令同时输出命令到文件 常和管道`|`一起使用 ### find ## 正则表达式 * `^` 匹配输入字符串的开始位置 * `[0-9]+` \]

posted @ 2023-04-10 16:53  Air-JoJo  阅读(93)  评论(0)    收藏  举报