Loading

Should Know To Shell

学习资料:

The Missing Semester of Your CS Education

The Shell OverView

$ doller 符号,表示普通用户
# pound 符号,表示 root 用户

还需要知道的一点是输入流与输出流之间的隔离

$ # echo 500 > hello.txt // 因为前面有 # 符号,所以该语句整个都是由 root 权限运行的
$ sudo echo 500 > hello.txt
//因为一个是输入流(input of echo) 和这 输出流(output to hello.txt),这两个是隔离的,所以 sudo 程序运行了 echo and 500,但是shell 打开了 hello.txt,又因为此时 SHELL 是普通用户,所以后面的写入操作是普通权限写入

另外一种办法是利用 pipe promt

$ echo 500 | sudo tee hello.txt

当然还有一个方法

$ sudo su
#

The Shell Scripting

$ foo=bar // 定义了一个变量,注意没有空格
// 如果这样定义
$ foo = bar // 这意味着启动 fool 程序,携带第一参数 =,第二参数 bar
$ echo $foo //prints the conttent of foo variable
bar
// 这 single quote and double quote 的区别
$ echo "Hello $foo"
Hello bar
$ echo 'Hello $foo' // single qutoe 将不会 expaned string foo
Hello $foo

写一个脚本

$ vim mcd.sh
mcd() {
	mkdir -p "$1" // 脚本中的 $0 - $9 指的是运行函数的时候,整个一行以 sapce 隔开的参数
	cd "$1"
}
$ source mcd.sh
$ mcd test // 脚本运行时候,会把 $0 扩展成 mcd 程序, $1 扩展成 test

$? // 上一个命令的错误代码
$_ // 表示上一个指令的最后一个参数
!! // 敲下 enter 键,!!将会被替换成上一个命令,经常配合 Permision Denied 使用
< // 通过标准输入获取内容
> // 将东西放入标准输出
grep foobar mcd.sh // 从 .sh 脚本搜索 foobar
false ; echo "This is " // concatenate commands using a semicolon in hte same line
foo=$(pwd) // 得到 pwd 命令的输出-当前工作目录并将其存储在 foo 变量中
echo "We are in $(pwd)" // 因为是双引号,所以 thing will be expanded

cat <(ls) <(ls ..) // process substitution, 具体还是没理解,感觉像是 cat 执行了两遍 cat <(xx); cat <(xx)

sample example

echo "Starting program at $(date)"  # 打印出现在的时间,同时可以指定不同的格式

echo "Running program $0 with $# arguments with pid $$" # $# 表示这个命令的参数数量,$$ 表示这个命令的进程 ID

for file in "$@"; do # 表示所有命令参数的集合
	grep foobar "$file" > /dev/null 2> /dev/null #将 grep 命令的输出重定向到 dev/null,dev/null 就像是 unix 系统中的特殊设备,定位到此处表示 discarded。> 表示重定向标准输出 and 2> 表示重定向标准错误输出,因为流之间的分开的,所以需要告诉 bash 如何处理其中每一个流
	if [[ "$?" -ne 0 ]]; then # #? 表示上面 grep 命令执行后的错误代码,-ne 是 not eaqul 好比其他语言中的 不等于, [[]] 好比 C 语言中的 ()
		echo "File $file does not have any foobar, adding one"
		echo "# foobar" >> "$file" # 追加 # foobar 字符串到 "$file" 文件中
	fi
done

# for in ; do
# done

# if [[]]; then
# fi
$ ls
example.sh image.png mcd.sh project1 project42
$ ls *.sh # *表示任何内容 所以 *.sh 表示匹配以.sh结尾的名称的文件
example.sh mcd.sh
$ ls project? # ? 表示只匹配一个任意字符
project1
# 花括号 curly braces 是 combine command 一个普遍的使用方式
$ convert image.png image.jpg
$ convert image.{png.jpg} # 按下 tab 键 将扩展成上面的样子
$ touch foo{,1,2,10} # tab后 -> touch foo foo1 foo2 foo10
$ touch project{1,2}/src/test{1,2,3}.py //
$ touch project1/src/test1.py project1/src/test2.py project1/src/test3.py project2/src/test1.py project2/src/test2.py project2/src/test3.py
 
# 结合星号 asterisk and 花括号 curly braces
$ touch {foo,bar}/{a..j}
$ touch foo/a foo/b foo/c foo/d foo/e foo/f foo/g foo/h foo/i foo/j bar/a bar/b bar/c bar/d bar/e bar/f bar/g bar/h bar/i bar/j

$ diff <(ls foo) <(ls boo) # 比较两者输出的 difference

.py

#!/usr/bin/env python
# 上面别称作 magic line,当我们使用 ./xx.py ,shell 将会解释上面的指令,携带参数 "python" 调用 env command,效果就是将会从环境变量 python 的路径启动 python interpreter 去解释该脚本
import sys
for arg in reversed(sys.argv[1:]): #
	print(arg)

shellcheck

Sometime maybe it's tricky to debug

这个命令将会检查 .sh 文件,给予 警告和 syntactic errors

$ shellcheck mcd.sh

tldr

convert + ffmpeg + tar
这是一个命令行程序,它的作用是提供一些关于该命令可解释的示例 explantory examples

$ brew install tldr# homebrew, mac 的包管理工具
$ tldr convert
convert # 处理图像的 command

ImageMagick image conversion tool.
More information: <https://imagemagick.org/script/convert.php>.

- Convert an image from JPG to PNG:
    convert image.jpg image.png

- Scale an image 50% its original size:
    convert image.png -resize 50% image2.png

- Scale an image keeping the original aspect ratio to a maximum dimension of 640x480:
    convert image.png -resize 640x480 image2.png

- Horizontally append images:
    convert image1.png image2.png image3.png +append image123.png

- Vertically append images:
    convert image1.png image2.png image3.png -append image123.png

- Create a GIF from a series of images with 100ms delay between them:
    convert image1.png image2.png image3.png -delay 10 animation.gif

- Create an image with nothing but a solid background:
    convert -size 800x600 "xc:#ff0000" image.png

- Create a favicon from several images of different sizes:
    convert image1.png image2.png image3.png image.ico
$ tldr ffmpeg
ffmpeg #处理 video
$ tldr tar
tar #解压缩文件/目录

find - fd alternative

$ find . -name src -type d # . 表示 current fold, -name 搜索的名称,-type 文件类型 ; 效果 recursively go throught the current folder 递归遍历当前的目录
$ find . -path '**/test/*.py' -type f # **表示当前所有路路径,该效果是每到一个文件夹寻找 test/*.py 文件
$ find . -mtime -1 # -mtime -1 表示 modified time 一天内被修改的文件
$ find . -name "*.tmp" -exec rm {} \; # 找到这些文件的路径,通过 rm 删除这些文件

locate

find 通过遍历目录结构来寻找某样目录或者文件

但是 locate 通过像数据库一样,建立索引结构,通过索引减少搜索时间和次数

$ locate docker
$ updatedb # 更数据索引结构 - 不是很清楚在什么时候使用

grep - fzf alternative

用来搜寻文件内容

$ grep foobar mcd.sh # 搜索 foobar 字符串,在 mcd.sh 文件中
$ grep -R foobar . # 递归搜索 foobar 字符串,在当前目录下

rg

rg 也是一个命令行搜索工具

目标是替代 grep

$ rg "import request" -t filetype ~/ 
$ rg "import request" -t filetype -C 5 ~/ # 展示围绕搜索的字符串上下 5行的内容
$ rg -u --files-without-match "^#\!" -t sh # u 是为了搜索范围包括这个隐藏文件, 搜索不匹配后面的正则表达式的文件
$ rg "import" -t go -C 5 --stats  ~/Desktop # stats 输出额外的信息,例如行数、文件数量、打印的字符
/Users/lin/Desktop/client-go/listers/rbac/v1/role.go
16-
17-// Code generated by lister-gen. DO NOT EDIT.
18-
19-package v1
20-
21:import (
22-	v1 "k8s.io/api/rbac/v1"
23-	"k8s.io/apimachinery/pkg/api/errors"
24-	"k8s.io/apimachinery/pkg/labels"
25-	"k8s.io/client-go/tools/cache"
26-)

27404 matches
27139 matched lines
19319 files contained matches
23291 files searched
7472153 bytes printed
220173685 bytes searched
3.530092 seconds spent searching
1.788742 seconds

ag

ack 推荐-可以搜索文件内内容

brew install ack
两者都是类似的命令行 search tool

history

使用上下箭头是一种 print 我们使用过的命令的方式

但是 history 能检索更长时间段使用过的命令

$ history # 打印它所记录的所有历史命令
$ history 1 # 打印从第 1 行算起的所有历史命令
$ history | grep tar # 通过 pipe + grep 过滤命令

Ctrl+R

快捷键 Ctrl+R 向后搜索历史命令,这是大部分系统都拥有的功能

$ dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
failing bck-i-search: conver_

fzf

模糊搜索工具fzf的安装和使用 --转载
Fuzzy finder(fzf+vim) 使用全指南 -- 转载

fuzzy matching 模糊搜索工具,我们可以搭配 cat 命令使用

这是一个很强大的工具,能配合很多工具使用

安装

$ brew install fzf
# 到对应的安装目录下执行 install 二进制文件
# yes 默认绑定快捷键后
$ source ~/.zshrc # 执行对应的 shell 配置文件
$ cat xxx | fzf
$ Ctrl+R 此时会非常好用了

切换当前工作目录

再比如进入到某个文件夹下面,使用 fzf 的过滤选择真是太方便了

cd $(find * -type d | fzf)

切换 git 分支

git checkout $(git branch -r | fzf)

fd

类比 find 的工具,也是用来搜索文件的工具

$ tldr fd
fd pattern

- Find files that begin with "foo":
    fd '^foo'

- Find files with a specific extension:
    fd --extension txt

- Find files in a specific directory:
    fd pattern path/to/directory

- Include ignored and hidden files in the search:
    fd --hidden --no-ignore pattern

- Execute a command on each search result returned:
    fd pattern --exec command

broot

不是很懂这个工具,emmm

posted @ 2021-08-28 08:33  zhixlin  阅读(54)  评论(0编辑  收藏  举报