用的较少的关键字命令:
例子:
```
at 10am mar 31 2015
at> echo "taxes due"
at> ^D(ctrl+D代表存储该任务)
```
atq:显示已经预定的任务
atrm job-d:删除某个设定的任务
```
* * * * * command to be excuted
- - - - -
| | | | |
| | | | +-------day of week(0 to 6)
| | | +---- month (1 to 12)
| | +---------day of month (1 to 31)
| +----- hour (0 to 23)
+---------min(0 to 59)
```
例子:
```
crontab -e
5 * * * * echo "shell command crontab " >> /Users/liudong/shell_learning
wq #save and quite crontab job
```表示每隔5分钟执行命令中的任务
seq 100 > numbers.txt #生成1-100,并写入到numbers.txt中
head -3 numbers.txt #显示前3行
tail -5 numbers.txt #显示后5行
head -65 numbers.txt | tail -5 >log.txt # 显示61-65行,并写入到log.txt中
diff file1 file2
-c: 指定显示第几个字符
-d: 指定列与列之间的分隔符
-f:指定显示哪些列
例子:
$ cut -d: -f1-5 /etc/password #展示文件/etc/password 文件的1-5列的内容,分隔符为:
output:
##
nobody:*:-2:-2:Unprivileged User
root:*:0:0:System Administrator
daemon:*:1:1:System Services
_uucp:*:4:4:Unix to Unix Copy Protocol
_taskgated:*:13:13:Task Gate Daemon
_networkd:*:24:24:Network Services
_installassistant:*:25:25:Install Assistant
_lp:*:26:26:Printing Services
$ date | cut -c1-5 #显示date输出的前5个字符
output:2019年
例子:将文件file1 file2 file3的内容进行合并
首先查看合并前的3个文件的内容
$ cat file #file文件的内容
xiongdan 200
lihaihui 233
lymlrl 231
$ cat file2 #testfile文件的内容
liangyuanm ss
$ cat file3 #testfile1文件的内容
huanggai 56
zhixi 73
再执行合并显示命令:
$ paste file1 file2 file3
output:
xiongdan 200
lihaihui 233
lymlrl 231
liangyuanm ss
huanggai 56
zhixi 73
例子:
$ cat test
aa
aa
cc
cc
bb
bb
yy
zz
$uniq test
aa
cc
bb
yy
zz
例子:
tr '[a-z]' '[A-Z]' < filename #将小写转为大写
tr '|' '~' < filename # 使用'~'替换文件中的'-'字符。
$ sort filename #按照每行的首字母的阿拉伯顺序排序
$ sort -d filename # 按照字典排序 (类似于上面)
$ sort -r filename #反向排序
$ sort +num filename #按照第num列的内容进行排序
$ echo "Welcome to Shell Scripting" > log.txt #log.txt的内容被设置为字符串内容
$ echo "Welcomet to shell scriptin" >> log.txt #字符串的内容将被添加到文件末尾
$ ls > log.txt #将ls命令的输出内容输入到log.txt中
$ gcc hello.c 2 > error_file #编译hello.c,如果发生了错误,就将错误内容重定向到error_file
$ find . -name "*.sh" > success_file 2> /dev/null # 将find命令的结果输入到success_file中,如果发生了错误,就将错误内容丢弃掉(/dev/null 代表丢弃任何输入到该字符设备的内容)
$ find . -name "*.sh" &> log.txt #将输出结果和错误一起重定向到log.txt
$ find . -name "*.sh" > log.txt 2>&1 #将结果重定向到log.txt,并将错误重定向到output中,既log.txt
$ echo "File needs an argument" 1>&2 #将output重定向到错误流中
char | 含义 | 例子 | 可能的输出 |
---|---|---|---|
* | 匹配任意个任意字符或数字 | $ ls –l .c file | Sample.c, hello.c, file1, file_2, filebc |
? | 匹配任意一个字符 | $ ls -l file? | filea, fileb, file1 |
[…] | 匹配中括号中的任意一个字符 | $ ls -l file[abc] | filea, fileb, filec |
$ touch file{1,2,3}
$ ls
file1 file2 file3
$ mkdir directory{1,2,3}{a,b,c}
$ ls
output:directory1a directory1b ....
char | 含义 | 例子 | 输出 |
---|---|---|---|
> | 输出重定向 | ls > ls.out | 将ls命令的输出写入到文件ls.out中 |
>> | 输出重定向(末尾添加的方式) | ls >>ls.out | |
< | 输入重定向 | tr ‘a’ ‘A’ < file1 | tr命令不再从键盘读入内容,转而从file1中读取内容 |
|| 逻辑或 | $ test $x -gt 10 | $x -lt 15 | |
&& | 逻辑与 | $ test $x -gt 10 && $x -lt 15 | 检查x的值是否处于10-15之间 |
例子:
$ vi file3 #通过vim打开file3
#在命令模式下,键入命令::set hlsearch #这样会高亮显示搜索匹配到的字符串。
:set ic #搜索匹配时,忽略大小写
:set noic #搜索匹配时,区分大小写。mac系统默认是不区分大小写的。
搜索及替换命令:
命令 | 描述 |
---|---|
/pat | 在打开的文件中搜索pat,并将光标cursor移动到匹配的字符串处 |
/ | 重复上一次的搜索 |
:%s/old/new/g | 在打开的文件中进行全局替换,将old全部替换成new |
:#,#s/old/new/g | 将#-#行之间的old内容替换为new. |
/^love/ | 高亮显示以love开始的行 |
/love$/ | 高亮显示以love结尾的行 |
/^love$/ | 高亮显示内容为love的行 |
/l.ve/ | .为通配符,可以匹配到love lxve live … |
/o*ve/ | *为数量通配符 可以匹配到ve ove oove ooooove |
/[Ll]ove/ | 只能匹配到love Love |
/ove[a-z] | 高亮显示ovea-ovez |
/^[A-Z]…$/ | 匹配以大写字母开头,后面只有2个字符的行 |
/^[A-Z]*[a-z]*3[0-5]/ | 高亮显示任意以30–35结尾的行 |
/[a-z]*\ ./ | 高亮显示任意包含小写字母,并且以.结尾的行 |
grep content file_name content和file_name都可以使用通配符
g:globally RE:regular expression p: print out
grep -n :同时显示行号
grep -i :模糊大小写
grep -v :显示非匹配行
grep -l ‘Nuts’ *: 列出当前目录下的包含"Nuts"的文件
grep -c ‘Nuts’ sample.txt:显示匹配到的总行数
grep -w ‘Nuts’ sample.txt:显示整个单词匹配到样式的行
元字符含义:
元字符 | 功能 | 例子 | 描述 |
---|---|---|---|
^ | 行开始 | ‘^mango’ | 显示以"mango"开头的行 |
$ | 行结束 | ‘mango$’ | 显示以mango结尾的行 |
. | 匹配单个字符 | m…o | 显示包含m,后面接2个字符,后面是o的行 |
* | 匹配0或多个*号前面的字符 | ‘*mango’ | 显示包含0或多个空格,后面接mango的行 |
[] | 匹配中括号集合中的任意一个 | [Mm]ango | 显示包含Mango或者mango的行 |
[^] | 匹配不属于中括号集合中的任意一个 | ‘[^A-M]ango’ | 显示不包含A-M,并且后面接ango的行 |
< | 以什么开头的单词 | ‘< mango’ | 显示以mango开头的行 |
> | 以什么结束的单词 | ‘mango>’ | 显示以mango结尾的行 |
0:代表上一条语句执行成功;非0:代表上一条语句执行失败。
例子:
$ ls
$ echo $?
output:0
$ ls /root
$ echo $?
output: 1
处于两个``之间的字符会被当做shell命令处理。
例子:
$ echo "Hello `whoami`"
output:Hello liudong
$ echo "Hello $(whoami)"
例子:
$pwd
output:/Users/liudong/shell_learning
$ dirname="$(basename $(pwd))" #只显示当前目录
$ echo dirname
outpu:shell_learning
&:代表该条shell命令将会在后台运行;
&&:必须在第一条语句成功执行后,第二条语句才会执行。
$ ls /home/liudong && echo "Command executed successfully"
output: Command executed successfully
$ ls /root && echo "Command executed successfully"
||:必须是第一条语句执行失败后,第二条语句才会执行。
$ ls /root || echo "Command execution failed"
是非条件表达式判断。
$ person=“liudong”
$ echo “$person” # liudong
$ echo ‘$person’ # $person
$ echo $person #$person
父进程声明的变量,可以通过加关键字export,让其对子进程可见,但是子进程声明的关键字不可能对父进程可见。
每当执行另一个shell脚本时,就会产生一个子进程。
$ person="liudong"
$ export person
$ readonly person="liudong"
$ unset person
output:bash: unset: person: cannot unset: readonly variable
另外一种只读变量的声明方式:
$ Declare -r person="liudong"
符号 | 含义 |
---|---|
$0 | shell脚本名称或者命令名 |
$1-$9 | 参数1-9 |
${10} | 参数10 |
$# | 参数的总个数 |
$* | 显示所有的参数 |
$@ | 同$*,除非被双引号包起来 |
“$*” | 按照格式"$1 $2 $3"来显示参数 |
“$@” | 按照格式"$1" “$2” “$3” |
set:执行脚本时,不一定通过命令行来传递参数,可以通过set命令来设置参数
$ set USA Canada UK France
$ echo $1
$ echo $2
$ echo $3
$ echo $4
shift:参数偏移设置。
#!/bin/bash
echo "All arguments passed are as follow:"
echo "$*"
echo "shift by one position:"
shift
echo "value of positional parameter $1 after shift:"
echo $1
echo "shift by two positions:"
shift 2
echo "value of positional parameter $1 after two shifts:"
echo $1
inputs:sh shift.sh one two three four
outputs:
All arguments passed are as follow:
one two thress four \n
shift by one position:
value of positional parameter two after shift:
two
shift by two positions:
value of positional parameter four after two shifts:
four
所以shift每次偏移量均是基于当前位置进行偏移的。
旧参数存储:
$set alan john dennis
$1 is alan $2 is john $3 is dennis
$ oldargs=$* #将旧参数保存在临时变量oldargs中
$ set $oldargs #将旧参数取回。
#!/bin/bash
USAGE="usage: $0 -x -y"
while getopts :xy: opt_char
do
case $opt_char in
x)
echo "option x was called."
;;
y)
echo "option y was called .Argument called is $OPTARG"
;;
\?)
echo "$OPTARG is not a valid option."
echo "$USAGE"
;;
esac
done
input:sh getopt.sh -x
output:option x was called.
input:sh getopt.sh -y ggggggggggggg
output:option y was called .Argument called is ggggggggggggg
input:sh getopt.sh -y gggggggggg -x
output:option y was called .Argument called is ggggggggggggg
option x was called.
这里读取的时候,因为x后面是没有接 O P T A R G , 所 以 − x 后 面 的 参 数 不 会 被 读 取 , 而 c a s e y 后 面 接 了 OPTARG,所以-x 后面的参数不会被读取,而case y后面接了 OPTARG,所以−x后面的参数不会被读取,而casey后面接了OPTARG,所以-y 后面接的参数会被读取。
例子:
#!/bin/bash
MY_PARAM=${1:default}
echo $MY_PARAM
格式:
${num:-value} # num:表示设置第几次参数的默认值;value代表默认参数的值。注意前面要带一个-
当然,默认参数是指当没有给指定位置的参数传值时,使用默认参数,如果传了值,就会使用传递的参数。
例子:
#!/bin/bash
FRUITS=(Mango Banana Apple)
echo ${FRUITS[*]}
echo $FRUITS[*]
echo $FRUITS[2]
FRUITS[3]=Orange
echo $FRUITS[*]
output:
Mango Banana Apple
Mango[]
Mango[2]
Mango[]
声明array变量的多种方式:
1 #!/bin/bash
2 FRUITS=(Mango Banana Apple)
3 echo ${FRUITS[*]}
4 echo $FRUITS[*]
5 echo $FRUITS[2]
6 FRUITS[3]=Orange
7 echo $FRUITS[*]
8 declare -a fruit=('Mango' 'Banana' 'Apple' 'Orange' 'Papaya')
9 declare -a array_name=(word1 word2 word3 word4) #注意:等号左右两边是不能加空格的哦
10 echo ${fruit[0]}
11 echo ${fruit[1]}
12 echo "all the fruits are ${fruit[*]}"
13 echo "the number of elements in the array are ${#fruit[*]}"
14 unset fruit
还有另外一种初始化方式:
$countries=(USA [3]=UK [2]=Spain)