文章目录
Linux 提供了很多专业的shell命令行工具,这些工具通过管道操作(|)可以连接输入和输出,进而组合出更为强大的功能。命令手册可以通过man <命令>获取,这些手册是最权威的解释,优先级应高于所有网上的二手解答,包括我这一篇。如果想快速入门,可以参考计算机缺失的一课。
linux目录结构
Linux下的目录的命名规则是 Filesystem Hierarchy Standard,特定的目录下存放相应功能的文件:(图片来自文章)

linux包安装
linux不同发行版有不同的包命名,而且不同时间的发行版有不同版本的包。当配置好仓库地址(如arch下/etc/pacman.conf),可以使用包管理器pacman检索包(其他发行版请参考自己的手册,如Debian请man apt)。
# 检索软件包
pacman -Ss <软件名称>
# 查询包详细信息
pacman -Qi <软件包名称>
当你不熟悉包管理器的命令使用时,可以访问pkg检索当前你使用的系统所对应的包名称,可视化界面很好,但是比命令行效率低,适合新手入门使用。
shell脚本
- set -x 显示每一行 set +x取消显示
管道与xargs
管道可以应用到ssh的标准输入(例子来自ysyx的教程),将当前目录中的python脚本用tar打包后,注入到ssh的标准输入,并使用重定向将标准输出定向到远程主机的test.tar.bz2
find . -maxdepth 1 -name "*.py"|xargs tar cj| ssh greatofdream@[远程主机] '>test.tar.bz2'
xargs可以将标准输入或者管道输出转变为命令行参数,具体用法
拆分列输出
ps输出一系列的文本,取出第2列
- ps -ef|head -5 |tr -s " "|cut -d " " -f 2|grep -v “PID”
tr -s可以将多个空格变成一个空格,cut选择第二列,grep -v 去除包含PID的行 - awk相当于是tr和cut的结合体
ps -ef|head -5 |awk ‘{print $2}’ |grep -v “PID” - 其实对于这个问题,ps是有对应的选项的
ps -e --no-headers -o pid|head -4
替换字符
上面使用tr替换字符,而sed可以利用正则表达式来进行更强大的匹配替换
比如上面最后例子中的文本输出前面有一串空格,将其匹配出来并替换为空
ps -e --no-headers -o pid|head -4|sed "s/^ *//"/
引号
" "双引号中变量可以替换,单引号不可以
如果传递的变量中有*或?的文件通配符时,会按照路径展开。加上引号可以避免展开
message="Hello*"
echo $message
双引号中嵌套使用双引号时,使用\转义。
单引号中无法嵌套使用单引号,需要单独转义
$?最近一条命令的返回值$@为命令参数,shift可以移动位置参数
$()可以将命令输出为字符串,``也可以实现同样的效果
$(())可以进行数值运算
select多选
PS3="question"
select item in${menu[@]}; do
echo "$item"
done
逐行读取文本
xxx.sh target < test.txt
#script
while read server; do
echo "$server $@"&#后台执行
done
wait#等待所有命令执行完成
可以在while中指定读入脚本
xxx.sh test.txt target
#script
file =$1
shift
while read server; do
echo "$server $@"&#后台执行
done<"$file"
wait#等待所有命令执行完成
makefile
在每行前面加上@可以避免输出对应行命令
tee输出文本文件同时进行管道输出
TMPFILE=/tmp/xxx.log.$$ #$$ 记录pid的值,利用这个变量避免文件名重复
{#可以书写多条命令
echo "date :$(date)"
mount -o rw,remount /dev/sda
mount -o ro,remount /dev/sda
}2>&1|tee $TMPFILE|logger -t "mountlog"
rm $TMPFILE
iconv可以实现编码转换mail可以发送邮件
shell字符串匹配
?匹配单个字符,*匹配任意内容,[0-9]在中括号内的内容匹配一个
详细介绍
比如希望将某个文件夹中的runxxxx变成run0000xxxx,利用makefile进行匹配并执行软链接操作,只需要make extend 即可制作所有软链接
.PHONY: extend split
target:=$(wildcard run????)
extend: $(target:run%=run0000%)
run0000%: run%
echo $@
ln -s $^ $@
利用Makefile和shell脚本将文件夹中的文件分类,并分别建立到不同文件夹的软链接
0000%:
mkdir -p run$@
for root in $(wildcard run2092-2103/Jinping_1ton_Phy_20??????_0000$**.root);do echo $${root};ln -s $${root} run$@/$$(basename $${root}); done
其中利用了Makefile的二级展开$$
cal
cal [options] [[[day] month] year]
cal [options] [timestamp|monthname]
cal 显示日历,如未指定参数,显示当月的日历。
一共有两种历法可以使用,Gregorian(格里高历)和Julian(儒略历)。Gregorian在闰年的设置上有跳跃(注:此处指的是Gregorian在被100整除的年份不设置闰年),使得和太阳运行周期更为匹配。
默认情况下cal使用1752年9月3日作为Gregorian的采用时间,此后的日历采用形式使用Gregorian,之前的形式使用Julian。
(注:注意到跳变的日期,11天被移除
$ cal 9 1752
September 1752
Su Mo Tu We Th Fr Sa
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
)
使用--reform参数来指定仅使用某一种日历形式。
(注: 此处的--reform参数在bash命令行中没有找到,bash中对应的另外一个命令是
$ ncal -J 9 1752
September 1752
Su 6 13 20 27
Mo 7 14 21 28
Tu 1 8 15 22 29
We 2 9 16 23 30
Th 3 10 17 24
Fr 4 11 18 25
Sa 5 12 19 26
)
警告
-j
使用序列数字来展示日期,从1月1日开始计数。但并不意味着这个选项使用了Julian日历系统。
find
参考: Debian manual
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]
-
-H,-L,-P:指定对符号链接的搜索方式,
-D:指定debug模式,
-O:指定查询优化级别
上述参数详细查询manual -
starting-point可以指定搜索开始的目录 -
expression是find功能部分,由以下几部分构成-
Tests返回True,False,非常重要的一部分,基本上是find功能的主要实现位置
+n:大于某个数
-amin n: n分钟前的时刻接触过,当然可以改为-amin +n表示n分钟以前的任何时候接触过,注意两者区别在于前者是某个指定的分钟,后者是某分钟以前
perm:权限
size:大小
-regex patter:正则表达式提供了更强大的检索功能
等等其它关于文件属性的判断 -
Action执行命令
-exec command ;:对每一个符合条件的文件执行操作find . -amin +5 -exec ls -l '{}' \;-exec command {} +:将符合条件的文件作为参数执行一次操作find . -amin +5 -exec ls -l '{}' + -
Global options指定全局参数
-depth指定查询深度
-maxdepth指定最大查询深度
等等 -
Positional option仅影响跟随其后的Test和·Action
-daystart -
Operators将其它选项连接起来
-
实战例子
- 在
xxx路径有很多文件夹,里面有文件,需要删除包含yyy.fail文件的文件夹。解决方式可以利用find
find xxx -name "*.fail" -exec dirname {} \;|sort -u|xargs rm -r
本文深入探讨Shell脚本的基础知识与高级技巧,包括字符串匹配、多选、逐行读取文本等实用功能,同时介绍了ps、sed、cal、find等常用命令的实战应用,适合初学者和进阶用户提升技能。
1035

被折叠的 条评论
为什么被折叠?



