Shell基础
# shell基础
# 一、命令
详细用法请查看Linux命令大全搜索工具 v1.5.1.pdf (opens new window)
# 1、搜索命令用法
# 2、Linux命令分类
# 文件传输
bye、ftp、ftpcount、ftpshut、ftpwho、ncftp、tftp、uucico、uucp、uupick、uuto、scp
点击查看
实例
- ftp: 使用
ftp 127.0.0.1创建连接,输入用户名密码后连接成功,使用[m]get xxx、[m]put xxx上传下载文件,使用[m]delete删除远端文件,使用bye、exit、quit关闭连接 - scp: 远程拷贝到本机:
scp -r root@10.10.10.10:/opt/soft/mongodb /opt/soft/本机拷贝到远程:scp -r /opt/soft/mongodb root@10.10.10.10:/opt/soft/scptest
# 备份压缩
ar、bunzip2、bzip2、bzip2recover、compress、cpio、dump、gunzip、gzexe、gzip、lha、restore、tar、unarj、unzip、zip、zipinfo
点击查看
实例
gz: 打包并压缩:
tar -czf [目标文件名].tar.gz [原文件/目录名]解压并解包:tar -zxvf xxx.tar.gz -C dirname(指定解压路径)注:c参数代表create(创建),x参数代表extract(解包),v参数代表verbose(详细信息),f参数代表filename(文件名),所以f后必须接文件名。
zip: 压缩:
zip -qr [目标文件名].zip [原文件/目录名]解压:unzip [原文件名].zipbz2 打包并压缩:
tar -jcvf [目标文件名].tar.bz2 [原文件名/目录名]解压并解包:tar -jxvf [原文件名].tar.bz2注:小写j代表用bzip2算法来压缩/解压7z 压缩:
7z a [目标文件名].7z [原文件名/目录名]解压:7z x [原文件名].7zjar 压缩:
jar -cvf [目标文件名].jar [原文件名/目录名]解压:jar -xvf [原文件名].jar注:如果是打包的是Java类库,并且该类库中存在主类,那么需要写一个META-INF/MANIFEST.MF配置文件,内容如下:
Manifest-Version: 1.0
Created-By: 1.6.0_27 (Sun Microsystems Inc.)
Main-class: the_name_of_the_main_class_should_be_put_here
然后用如下命令打包:jar -cvfm [目标文件名].jar META-INF/MANIFEST.MF [原文件名/目录名],这样以后就能用“java -jar [文件名].jar”命令直接运行主类中的public static void main方法了。
# 文件管理
diff、diffstat、file、find、git、gitview、ln、locate、lsattr、mattrib、mc、mcopy、mdel、mdir、mktemp、mmove、mread、mren、mshowfat、mtools、mtoolstest、mv、od、paste、patch、rcp、rhmask、rm、slocate、split、tee、tmpwatch、touch、umask、whereis、which、cat、chattr、chgrp、chmod、chown、cksum、cmp、cp、cut、indent
# 磁盘管理
cd、df、dirs、du、edquota、eject、lndir、ls、mcd、mdeltree、mdu、mkdir、mlabel、mmd、mmount、mrd、mzip、pwd、quota、quotacheck、quotaoff、quotaon、repquota、rmdir、rmt、stat、tree、umount
# 磁盘维护
badblocks、cfdisk、dd、e2fsck、ext2ed、fdisk、fsck.ext2、fsck、fsck.minix、fsconf、hdparm、losetup、mbadblocks、mformat、mkbootdisk、mkdosfs、mke2fs、mkfs.ext2、mkfs、mkfs.minix、mkfs.msdos、mkinitrd、mkisofs、mkswap、mpartition、sfdisk、swapoff、swapon、symlinks、sync
# 系统设置
alias、apmd、aumix、bind、chkconfig、chroot、clock、crontab、declare、depmod、dircolors、dmesg、enable、eval、export、fbset、grpconv、grpunconv、hwclock、insmod、kbdconfig、lilo、liloconfig、lsmod、minfo、mkkickstart、modinfo、modprobe、mouseconfig、ntsysv、passwd、pwconv、pwunconv、rdate、resize、rmmod、rpm、set、setconsole、setenv、setup、sndconfig、SVGAText Mode、timeconfig、ulimit、unalias、unset
# 系统管理
adduser、chfn、chsh、date、exit、finger、free、fwhois、gitps、groupdel、groupmod、halt、id、kill、last、lastb、login、logname、logout、logrotate、newgrp、nice、procinfo、ps、pstree、reboot、renice、rlogin、rsh、rwho、screen、shutdown、sliplogin、su、sudo、suspend、swatch、tload、top、uname、useradd、userconf、userdel、usermod、vlock、w、who、whoami、whois
# 文本处理
awk、col、colrm、comm、csplit、ed、egrep、ex、fgrep、fmt、fold、grep、ispell、jed、joe、join、look、mtype、pico、rgrep、sed、sort、spell、tr、uniq、vi、wc
点击查看
实例
- grep: 多行匹配:
grep --color=auto -Pazo '<div>\s+</div>' [文件名/通配符].txt(-z 为多行模式、-P 为 Perl 正则表达式)
# 网络通讯
dip、getty、mingetty、ppp-off、smbd(samba daemon)、telnet、uulog、uustat、uux、cu、dnsconf、efax、httpd、ip、ifconfig、mesg、minicom、nc、netconf、netconfig、netstat、ping、pppstats、samba、setserial、shapecfg(shaper configuration)、smbd(samba daemon)、statserial(status ofserial port)、talk、tcpdump、testparm(test parameter)、traceroute、tty(teletypewriter)、uuname、wall(write all)、write、ytalk、arpwatch、apachectl、smbclient(samba client)、pppsetup
# 设备管理
dumpkeys、loadkeys、MAKEDEV、rdev、setleds
# 电子邮件与新闻组
archive、ctlinnd、elm、getlist、inncheck、mail、mailconf、mailq、messages、metamail、mutt、nntpget、pine、slrn、X WINDOWS SYSTEM、reconfig、startx(start X Window)、Xconfigurator、XF86Setup、xlsatoms、xlsclients、xlsfonts
# 其他命令
yes
# 博客
博客链接:
# 二、shell脚本相关
# 1、脚本格式
解析器
使用 cat /etc/shells 来查看系统提供的Shell解析器。 使用 echo $SHELL 查看默认使用的解析器
- 以
#!/bin/bash开头(用来指定解析器) - 使用sh/bash + 脚本不需要执行权限,直接使用脚本绝对路径或相对路径需要执行权限。
使用
bash(sh) x.sh的方式执行脚本,是在当前shell中打开一个子shell来执行脚本
使用./x.sh或source(.) x.sh是在当前shell执行,这也是每次修改完环境变量/etc/profile文件后,要执行source /etc/profile的原因
在子shell执行和父shell执行的区别是:环境变量的继承关系,比如在子shell设置的环境变量,在父shell是不可见的
# 2、变量
# 变量类型
- 局部变量:局部变量在脚本或命令中定义,仅在当前 shell 实例中有效,其他 shell 启动的程序不能访问局部变量;
- 环境变量:所有的程序,包括 shell 启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候 shell 脚本也可以定义环境变量;
- shell 变量:shell 变量是由 shell 程序设置的特殊变量。shell 变量中有一部分是环境变量,有一部分是局部变量。
# 定义变量
- 定义变量:
变量=值(中间不能有空格) - 使用变量
$变量或${变量} - 撤销变量:unset 变量名
- 声明局部变量:local 变量="xxx"
- 声明只读变量:readonly 变量(不能unset)
| -- | -- |
|---|---|
| global | 作用域从定义到shell结束或者变量被删除 |
| local | 作用域只在函数内部,函数参数是local的 |
# 参数扩展
- 去掉结尾的部分:
${var%pattern}: 去掉变量值末尾符合pattern的部分。例如,${filename%.*}去掉文件名中的扩展名。${var%%pattern}: 去掉变量值末尾符合pattern的最长部分。例如,${path%%/}去掉路径末尾的所有斜杠。
- 去掉开头的部分:
${var#pattern}: 去掉变量值开头符合pattern的部分。例如,${path#*/}去掉路径开头的第一个斜杠。${var##pattern}: 去掉变量值开头符合pattern的最长部分。例如,${path##*/}去掉路径开头的所有目录部分,只留下文件名。
- 替换内容:
${var/pattern/replacement}: 替换变量值中第一个匹配pattern的部分为replacement。例如,${filename/.txt/.bak}将.txt替换为.bak。${var//pattern/replacement}: 替换变量值中所有匹配pattern的部分为replacement。
- 默认值:
${var:-default}: 如果变量var未设置或为空,返回default的值。${var:=default}: 如果变量var未设置或为空,将其设置为default的值,并返回该值。
- 长度和子字符串:
${#var}: 变量var的长度。例如,${#filename}返回文件名的长度。${var:position:length}: 从变量var的position开始提取length个字符。例如,${filename:0:5}提取文件名的前五个字符。
# 通配符
| 通配符 | 作用 | 示例 |
|---|---|---|
| * | 匹配零个或多个字符。 | 例如,*.txt 匹配所有扩展名为 .txt 的文件。 |
| ? | 匹配一个单一字符。 | 例如,file?.txt 匹配 file1.txt、fileA.txt 等,但不匹配 file10.txt。 |
| [abc] | 匹配方括号内的任意一个字符。 | 例如,file[123].txt 匹配 file1.txt、file2.txt 和 file3.txt。 |
| [a-z] | 匹配方括号内的字符范围。 | 例如,file[a-z].txt 匹配 filea.txt、fileb.txt 到 filez.txt。 |
| {a,b} | 匹配 {} 内的任意一个选项(用于文件名生成)。 | 例如,file{1,2}.txt 匹配 file1.txt 和 file2.txt。 |
| [!abc] 或 [^abc] | 匹配不在方括号内的任何一个字符。 | 例如,file[!1].txt 匹配 file2.txt、fileA.txt 等,但不匹配 file1.txt。 |
| ** | 匹配零个或多个目录(在 Bash 的 extglob 扩展中支持)。 | 例如,dir/** 匹配 dir 目录及其所有子目录和文件。 |
# 数组
- 定义数组:
arr=(value0 value1 value2) - 使用数组:
${数组名[下标]} - 获取元素:
${arr[*]}或${arr[@]} - 获取长度:
${#arr[@]}或${#arr[*]}
# 3、特殊变量
| 变量 | 含义 |
|---|---|
| $'\n' | 获取换行符 |
| $1~$n | 添加到Shell的各参数值。$1是第1参数、$2是第2参数…十以上的参数需要用大括号包含${10} |
| shift | 位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢弃,$0不移动。不带参数的shift命令相当于shift 1。 |
| $$ | Shell本身的PID(ProcessID) |
| $! | Shell最后运行的后台Process的PID |
| $? | 最后运行的命令的结束代码(返回值) |
| $- | 使用Set命令设定的Flag一览 |
| $* | 所有参数列表(所有参数看成一个整体)。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数 |
| $@ | 所有参数列表(每个参数区分对待)。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数 |
| $# | 添加到Shell的参数个数 |
| $0 | Shell本身的文件名 |
# 4、if条件判断
IF条件只能为命令(或脚本)返回值(比如./test.sh),[命令等同于test命令
| 条件 | 含义 |
|---|---|
| []和test | 在命令行里test expr和[ expr ]的效果相同(判断文件、判断字符串、判断整数) |
| [[ ]] | 内置在shell中的一个命令(支持字符串的模式匹配、逻辑组合可以不使用test的-a,-o而使用&& |
| -eq | 【数值比较】测试两个整数是否相等 |
| -ne | 【数值比较】测试两个整数是否不等 |
| -gt | 【数值比较】测试一个数是否大于另一个数 |
| -lt | 【数值比较】测试一个数是否小于另一个数 |
| -ge | 【数值比较】大于或等于 |
| -le | 【数值比较】小于或等于 |
| 逻辑关系 | 命令间的逻辑关系, 逻辑与:&& , 逻辑或: |
| = | 【字符串比较】等于 两边要有空格 |
| != | 【字符串比较】不等 |
| > | 【字符串比较】大于 |
| < | 【字符串比较】小于 |
| -z | 【字符串比较】string 字符是否为空,空着真,非空为假 |
| -n | 【字符串比较】string 字符串是否为不空(长度非0),空为假 非空为真(if [ -n "" ]) |
| -e | 【文件测试】file 文件是否存在 |
| -f | 【文件测试】file 是否为普通文件(if [ -f "" ]) |
| -d | 【文件测试】file 是否为目录(if [ -d "" ]) |
| -r | 【文件测试】file 文件对当前用户是否可读 |
| -w | 【文件测试】file 文件对当前用户是否可写 |
| -x | 【文件测试】file 文件对当前用户是都可执行 |
| -z | 【文件测试】是否为空 为空则为真 |
| -a | 【文件测试】是否不空 |
| -s | 【文件测试】文件存在且至少有一个字符时为真 |
| -c | 【文件测试】文件存在且为字符型特殊文件时为真 |
| -b | 【文件测试】文件存在且为块特殊文件时为真 |
| -r | 【文件权限】有读的权限(read) |
| -w | 【文件权限】有写的权限(write) |
| -x | 【文件权限】有执行的权限(execute) |
| =~ | 正则匹配 if [[ $line =~ ^java.library.path=(.*)$ ]] |
[] 和 [[]]的区别
注意:使用[]和[[]]的时候不要吝啬空格,每一项两边都要有空格,[[ 1 == 2 ]]的结果为“假”,但[[ 1==2 ]]的结果为“真”!
1.首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。"[[",是关键字,许多shell(如ash bsh)并不支持这种方式。ksh, bash(据说从2.02起引入对[[的支持)等支持。"["是一条命令, 与test等价,大多数shell都支持。在现代的大多数sh实现中,"["与"test"是内部(builtin)命令,换句话说执行"test"/"["时不会调用/some/path/to/test这样的外部命令(如果有这样的命令的话)。
2.[[]]结构比Bash版本的[]更通用。在[[和]]之间的所有的字符都不会被文件扩展或是标记分割,但是会有参数引用和命令替换。 用[[ ... ]]测试结构比用[ ... ]更能防止脚本里的许多逻辑错误。比如说,&&,||,<和>操作符能在一个[[]]测试里通过,但在[]结构会发生错误。
3.(( ))结构扩展并计算一个算术表达式的值。如果表达式值为0,会返回1或假作为退出状态码。一个非零值的表达式返回一个0或真作为退出状态码。这个结构和先前test命令及[]结构的讨论刚好相反。
4.[ ... ]为shell命令,所以在其中的表达式应是它的命令行参数,所以串比较操作符">" 与"<"必须转义,否则就变成IO改向操作符了(请参看上面2中的例子)。在[[中"<"与">"不需转义; 由于"[["是关键字,不会做命令行扩展,因而相对的语法就稍严格些。例如 在[ ... ]中可以用引号括起操作符,因为在做命令行扩展时会去掉这些引号,而在[[ ... ]]则不允许这样做。
5.[[ ... ]]进行算术扩展,而[ ... ]不做
6.[[ ... && ... && ... ]] 和 [ ... -a ... -a ...] 不一样,[[ ]] 是逻辑短路操作,而 [ ] 不会进行逻辑短路
# 5、流程控制
# if判断
注意: 1.if后要有空格 2.条件前后要有空格
- 单分支
if [ 条件判断 ]; then
# 程序
fi
# 或者
if [ ]
then
# 程序
fi
- 多分支
if [ 条件判断 ]
then
# 程序
elif [ 条件判断 ]
then
# 程序
else
# 程序
fi
# case语法
注意: 1. case行尾必须为单词in 2. 每个模式匹配必须以')'结束 3. ';;'表示命令序列结束(同java的break)
case $变量 in
"值1")
# 变量的值等于值1, 则执行
;;
"值2")
# 变量的值等于值2, 则执行
;;
*)
# 变量的值都不是以上的值, 则执行
;;
esac
# for循环
# for (( 初始值;循环控制条件;变量变化 ))
for (( i = 0; i < n; i++ )); do
done
# 或者
# for 变量 in 值1 值2 值3...
for i in {1..5} ; do
done
$*和$@的区别:
- 不被双引号("")包含时: 都以$1 $2...$n形式输出
- 被双引号("")包含时: $*将所有参数看做整体"$1 $2...$n" $@将各个参数分开"$1" "$2"..."$n"
# while循环
while [ 条件判断 ]; do
# 程序;可使用 break 或 continue
done
# Until循环
until condition
do
command
done
# 6、read读取控制台输入
read [选项] [参数]
# 选项 -p: 指定读取时提示符 -t: 指定读取等待时间(s秒),不加默认一直等待
# 参数 指定读取时的变量名
#!/bin/bash
read -t 3 -p "3s内输入名称: " username
echo $username
# 7、函数
# basename 截取文件名
# 语法
basename [string/pathname] [suffix] # 删掉所有前缀包含最后一个'/'(若指定suffix,则将其删掉), 将字符串显示
# 示例
[banana@hadoop10 MyLog]$ basename /home/banana/MyLog/test.sh .sh
test
# dirname 截取绝对路径
dirname 文件绝对路径
# 示例
[banana@hadoop10 MyLog]$ dirname /home/banana/MyLog/test.sh
/home/banana/MyLog
# 自定义函数
注意:
- 使用时应该先声明函数, 再调用(shell脚本逐行执行)
- 返回值: 可以用$?获取返回值, 若不加, 为最后一个命令的运行结果
# 声明
[function] funname[()]
{
Action;
[return int(0-255);]
}
# 调用
funname para1