第一章:概览 shell:
计算机提供给用户的一种文字接口,核心功能 - 允许用户执行程序,输入并获取某种半结构化的输出; shell是一个编程环境,所以它具备变量、条件、循环和函数。 当你在 shell 中执行命令时,实际上是在执行一段 shell 可以解释执行的简短代码。 如果要求 shell 执行某个指令,但是该指令并不是 shell 所了解的编程关键字,那么它会去查询环境变量 $PATH,搜索由:
分隔的一系列目录,基于名字搜索该执行程序
基本使用 shell的界面(bash@zsh) #
开头是注释,提示信息,hostname
是主机名,~
指当前工作目录是home
,$
表示当前用户不是root
用户,Last login...
打开一个新的window就会出现该提示
1 2 3 Last login: Tue Nov 3 17:59:22 on ttys007 $
基础命令: 使用 man [command]
来了解这些命令的详细信息
内置命令&变量: date, echo, which echo, $PATH, ls, cd, pwd, /(root path), ./(current path,relative), ../(parent path, relative), mv(用于重命名或移动文件), mkdir(新建文件夹), cp(复制文件)
1 2 3 4 5 6 7 8 9 10 11 $ $ ls -l /home total 0 drwxr-xr-x 3 user staff 96 12 9 2016 beginning _3_ /|\ |_____________|
1 2 3 4 5 6 7 8 9 10 Last login: Fri Nov 6 18:13:54 on ttys007 $ date 2020年11月 7日 星期六 16时09分15秒 CST $ echo hello DaiYing hello DaiYing $ echo $PATH /Users/hostname/.yarn/bin:/Users/hostname/.config/yarn/global/node_modules/.bin:/Users/hostname/.avn/bin:/Users/hostname/.nvm/versions/node/v8.9.4/bin:/usr/local /bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/hostname/.rvm/bin $ which echo echo : shell built-in command
在程序间建立连接
输入流,输出流,重定向(重定向方向 <, >重定向方向, >>追加内容方向) | (pipes)管道操作符,连接左边的输入到右边的输出 sudo(super user do)根用户
练习题:Mac OSX系统
新建tmp/missing/semester文件,按行向semester输入内容
练习
1 2 3 4 5 6 7 8 9 10 11 12 $ mkdir tmp $ cd tmp/ $ mkdir missing $ cd missing/ $ touch semester $ echo '#!/bin/sh' > semester $ echo 'curl --head --silent https://missing.csail.mit.edu' >> semester $ vim semester
第二章: shell工具和脚本 字符串区别
shell访问变量: 前缀$+变量名;如:$foo
1 2 3 4 5 foo=bar echo "$foo " bar echo '$foo' $foo
shell脚本控制流
Here is an example of a func that creates a dir and cd into it
$0
-script command
$1
~$9
- script command的参数
$@
script command的所有参数
$#
- script command参数个数
$?
-上一个script command
$$
-当前scrippt command的PID(Process Identification number)
!!
-使用sudo !!
执行上一个command(包含所有参数)
$_
-上一个命令的最后一个参数
1 2 3 4 5 6 7 8 9 10 #!/bin/sh mcd () { mkdir -p "$1 " cd "$1 " } source testShellFunc.sh
短路操作符
||, &&, ;
, 同一行命令可以用;
间隔,true
的返回码是0
,false
的返回码是1
1 2 3 4 5 true ; echo 'I can run!' false ; echo 'I can run again!'
linux中: | and ||, & and &&, &> and >
的区别:&
表示任务在后台执行,如要在后台运行|
表示管道,上一条命令的输出,作为下一条命令参数(输入)>
符号是指:将正常信息重定向; &>
可以将错误信息或者普通信息都重定向输出
命令替换:以变量的形式获取一个命令的输出
执行$(CMD)
,CMD
的执行结果会替换$(CMD)
的位置; 冷门应用-进程替换:<(CMD)
, 执行结果将会输出到一个临时文件而不是通过STDIN
传递 特殊的进程标识符: 0标准输入(stdin),1标准输出(stdout),2标准错误(stderr)
2>
重定向stderr;引申:&>
重定向stderr, >&2
,重定向到
stderr
-ne
means not equal to
, 查阅bash 条件表达式
或man test
(查test手册)
使用shellcheck
工具检查shell script错误
详见bash 条件表达式
test手册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/bin/bash echo "Starting program at $(date) " echo "Running program $0 with $# arguments with pid $$" for file in $@ ; do grep foobar $file > /dev/null 2> /dev/null if [[ $? -ne 0 ]]; then echo "File $file does not have any foobar, adding one" echo "# foobar" >> "$file " fi done Starting program at 2020年12月20日 星期日 14时54分51秒 CST Running program ./testfunc.bash with 2 arguments with pid 10741 File test1 does not have any foobar, adding one File test2 does not have any foobar, adding one
shell的 通配( globbing): {}, 正则 1 2 3 4 5 6 7 8 9 10 convert image.{png,jpg} convert image.png image.jpg cp /path/to/project/{foo,bar}.sh /newpath cp /path/to/project/foo.sh /path/to/project/bar.sh /newpath mv *{.py,.sh} folder diff <(ls foo) <(ls bar)
shebang
#!
语法使用脚本来指示解释器如何在unix/linux
下执行 例如: #!/bin/bash
;#!/usr/bin/perl
;#!/usr/bin/python
;#!/usr/bin/python3
;#!/usr/bin/env bash
如果不指定解释器,通常会默认为#!/bin/sh
,不过官方推荐使用#!/bin/bash
,sh和bash
在某些语法上有些不兼容,如条件判断[[]]
使用env
来执行非bash
脚本,env
会利用PATH
变量来定位脚本
参考
1 2 3 4 5 #!/usr/local/bin/python import sys for arg in reversed(sys.argv[1:]): print (arg)
查看命令
man -h
查看命令如何使用
使用TLDR
,一个很好的替代品,npm install -g tldr
全局安装
查找文件
find
工具
fd
更快更友好
locate
只能通过文件名来定位,且每天都会更新
1 2 3 4 5 6 7 8 9 10 11 12 find . -name src -type d find . -path '**/test/**/*.py' -type f find . -mtime -1 find . -size +500k -size -10M -name '*.tar.gz' find . -name '*.tmp' -exec rm {} \; find . -name '*.png' -exec convert {} {}.jpg \;
查找代码
grep
对输入文本进行匹配的通用工具, ack
, ag
等
rg
,ripgrep速度快,符合直觉
1 2 3 4 5 6 7 8 rg -t py 'import requests' rg -u --files-without-match "^#!" rg foo -A 5 rg --stats PATTERN
查找shell命令
history
访问shell中输入的历史命令, history | grep find
会打印包含find子串的命令
Ctrl+R
命令历史记录进行回溯搜索,可以配合fzf
使用,fzf
是一个通用对模糊查找工具
输入命令时,如果您在命令的开头加上一个空格,它就不会被加进shell记录中
bash_history或 .zhistory 来手动地从历史记录中移除
文件内导航
fasd
可以查找最常用和/或最近使用的文件和目录。基于 frecency
对文件和文件排序,也就是说它会同时针对频率(frequency )和时效( recency)进行排序
概览目录结构: tree
, broot
文件管理器: nnn
, ranger
课后练习
第一题:ls -AGulht
第二题:macro.bash ; polo.bash
第三题:check_run
第四题:find . -name '*.html' | xargs -0 zip -r output.zip
注意文件名不要相同,否则zip会抛错停止
第五题: find . ctime 10
其他练习&常用命令 ssh本地上传包文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 zip -r dist.zip dist scp dist.zip username@hostname:/path/in /dir/ username@hostname'"s' password: ssh username@hostname username@hostname'"s' password: cd /path/in /dir/ll unzip dist.zip mv old-dir save-old-dir mv dist old-dir