shell中的使用技巧1

    xiaoxiao2022-07-08  253

    关于for循环 linux风格的for循环 #IFS.OLD=$IFS #IFS=$'\n' #IFS=:" for var in lists do commands done

    其中lists默认以空格为分隔符,如果要自定义分隔符要用全局变量IFS,如果想只自定义使用一次随即恢复默认值,那么就是用IFS.OLD=$IFS

    C语言风格的for循环 for ((i=1,i<10,i++)) do commands done linux shell 普遍都是以((commands)) 来处理数字,只有(( )) 内的字符默认为变量或数字

    2. 关于if ; while 的判断式

    if commands then expresson fi while commands do expresson done commands 只用来判断退出码是否为0,若为0则执行expresson,否则不执行.shell可以用((commands))来做数字计算,并返回一个退出码,布尔值为TURE则返回码为0,就与C语言无二. 可以用[commands]来判断非数字类,><等字符需要用转义符,但一般都用-eq 这种去书写.

    3. << 重定向的使用

    bc << EOF 2+1 EOF echo "wei" >&testout exec 3>testout exec 1>testout echo "wei" >&3 exec 3>&- echo "wei" tree -a filename

    可以用<<自定义 ctrl+d 这种输入完毕的信号. 1,2输出重定向到testout可以用>&,而不必用两次>. 永久重定向可以用exec,关闭永久重定向也是exec 3>&-,自定义重定向可以自行设置除标准0,1,2之外最多到9的数字. 如果不想要输出,可以将其输出到/dev/null中去,/tmp是根目录下的临时文件目录,只保存一定时间,也可以输出到这里去. tree算是一个分叉重定向,可以同时输出到filename和屏幕,而无需使用2次>,如果要追加要使用选项 -a

    4. 一些通用的选项,便于记忆

    -a 显示所有对象 -c 生成一个计数 -d 指定一个目录 -e 扩展一个对象 -f 指定读入数据的文件 -h 显示命令的帮助信息 -i 忽略文本大小写 -l 产生输出的长格式版本 -n 使用非交互模式(批处理) -o 将所有输出重定向到的指定的输出文件 -q 以安静模式运行 -r 递归地处理目录和文件 -s 以安静模式运行 -v 生成详细输出 -x 排除某个对象 -y 对所有问题回答yes

    n表示显示数字行数,h表示用通用单位表示,a表示全部(包含隐藏)

    5. 局部变量与全局变量

    var="have" export var unset var

    局部变量与C语言不同,父/子域相互独立,互不相通,也就是子域不能使用父域的局部变量 全局变量与C语言的局部变量一样,子可以使用父全局变量,而无法修改父全局变量,只能在自己定义域内修改.

    6. 多线程,多进程,协程

    sleep 3 & coproc {sleep 3;} (sleep 3) bash

    bash 是一个启动子进程的命令,推出子进程使用exit,特别要注意的是子进程无法使用父进程的局部变量,这里尤其容易出错 而使用多进程的简单方式就是加()或者最后使用&字符. coproc为协程语法,有通信功能.

    7. 持久化变量理解 每次自定义的局部/全局变量重启计算机以后均会消失,可以修改文件来持久化变量 交互式shell配置读取顺序是 /etc/profile /etc/profiled/.sh ~/.bash_profile ~/.bashrc /etc/bashrc 非交互式shell配置读取顺序是  ~/.bashrc /etc/bashrc /etc/profiled/.sh* 仔细阅读文件脚本会发现很多顺序读取都是由第一个读取文件的脚本去书写的,区别在于/etc/profile ~/.bash_profile是交互式shell专有的,这里很容易在脚本中犯错,etc目录容易被系统更新修改  ~目录并不会使帐户间通用,尤其是在处理特殊运行脚本的帐号的时候尤其要注意

    8. yum pip卸载软件

    yum remove package_name yum erase package_name pip uninstall modlename

    remove可以卸载软件并保留数据,而erase则是卸载软件并删除数据

    9. 使用ssh , sftp 来实现win与linux的文件传输

    sftp weilin@192.168.0.104 get 192.168.0.104:/etc/passow c:\name put c:\name 192.168.0.104:/etc/name cd lcd scp file weilin@192.168.0.104:/etc/name scp weilin@192.168.0.104:/etc/name file

    使用sftp进行远程登录,而后可以使用shell操作linux,本机的环境前面要加l,L的小写.而后可以用put进行上传,或者使用get进行下载,如果已经知道了详细的目录文件名,可以使用scp直接远程复制.

    命令行脚本的编写技巧 一个书写选项后带参数的命令的例子 $ cat test17.sh #!/bin/bash # extracting command line options and values echo while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option";; -b) param="$2" echo "Found the -b option, with parameter value $param" shift ;; -c) echo "Found the -c option";; --) shift break ;; *) echo "$1 is not an option";; esac shift done # count=1 for param in "$@" do echo "Parameter #$count: $param" count=$[ $count + 1 ] done $ $ ./test17.sh -a -b test1 -d Found the -a option Found the -b option, with parameter value test1 -d is not an option $

    如果运行命令需要输入路径,那么$0变量也是路径,可以用name=$(basename $0) 来剥离路径,剩下命令名. $#可以用来统计参数的个数,但在使用变量时${$#} 是错误的,可以把$换成!来避免错误,${!#}. $* 与 $@的区别,$*是视参数集合为一个字符串,不可迭代出每个参数.$@视参数集合为迭代对象,可遍历出每个参数 用循环的时候可以用shift 来移动变量, $后只能跟一个字符来表示一个变量,如果变量名有非法字符比如空格,需要加{var car}

    如果命令行参数只能识别-a -b -c 而不能识别 -abc,这就需要使用getopt进行参数格式化

    $ cat test18.sh #!/bin/bash # Extract command line options & values with getopt # set -- $(getopt -q ab:cd "$@") # echo while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) param="$2" echo "Found the -b option, with parameter value $param" shift ;; -c) echo "Found the -c option" ;; --) shift break ;; *) echo "$1 is not an option";; esac shift done # count=1 for param in "$@" do echo "Parameter #$count: $param" count=$[ $count + 1 ] done

    set命令的选项之一是双破折线(–),它会将命令行参数替换成set命令的命令行值。然后,该方法会将原始脚本的命令行参数传给getopt命令,之后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数 冒号前为必须参数,冒号后面为可选参数,然而getopt不能处理带空格的参数,可以用getopts来解决

    $ cat test19.sh #!/bin/bash # simple demonstration of the getopts command # echo while getopts :ab:c opt do case "$opt" in a) echo "Found the -a option" ;; b) echo "Found the -b option, with value $OPTARG";; c) echo "Found the -c option" ;; *) echo "Unknown option: $opt";; esac done $ $ ./test19.sh -ab test1 -c Found the -a option Found the -b option, with value test1 Found the -c option $

    getopts 有着自动迭代功能 getopts ab:c opt,会把每次迭代结果传入变量opt, 上面ab是必须选项,如果出现t选项, 则会报错,并把未定义解释成?,若不让其报错,在a前加冒号 :ab

    最新回复(0)