shell
用powerShell有些也行
basics
basic commands
在执行程序时在后面使用 -h 或 --help 标记看提示; 在前面使用man查看手册;history打印历史命令
date打印日期、时间echo [参数1]打印[参数1]; 注意shell中用空格分隔的被认为是不同参数, 例如echo [参数1] [参数2]; 如果需要传递的参数包括空格, 用转义符号\;echo实际上是一个程序,可以直接用路径替代echo来执行$PATH环境变量, 是用:分隔的地址们which确定程序名(e.g.echo)代表的实际程序地址
navigation
shell 中的路径是一组被分割的目录.
在linux中绝对路径由/分割, 相对路径由\分割.
linux中, 路径开头的/ 代表的是系统的根目录,所有的文件夹都包括在这个路径之下, e.g. /bin/echo.
Windows中路径用\分割, 这是因为在Windows上每个盘都有一个根目录(例如:C:\)
pwd当前工作目录lslist目录下的所有文件(默认当前目录);ls -l [目录];ls *.shglobbing所有.sh后缀名文件;ls [文件名]?仅列举名字多一位的文件(?占一位);ls [文件名]+tab+tab可以筛选出包含这个名字的文件文件的属性:
drwxr-xr-xd表示目录; 此后三位一读, 依次为文件所有者,用户组与所有人的权限;r = read, w = write, x = executepowerShell中mode有d - Directory, a - Archive, r - Read-only, h - Hidden, s - System, l - Reparse point, symlink, etccat读出文件内容mvmoverm [文件]removecp [源] [末]copymkdirmake directoryfind递归查找文件# 查找所有名称为src的文件夹 find . -name src -type d # 查找所有文件夹路径中包含test的python文件 find . -path '*/test/*.py' -type f # 查找前一天修改的所有文件 find . -mtime -1 # 查找所有大小在500k至10M的tar.gz文件 find . -size +500k -size -10M -name '*.tar.gz' # 删除全部扩展名为.tmp 的文件 find . -name '*.tmp' -exec rm {} \; # 查找全部的 PNG 文件并将其转换为 JPG find . -name '*.png' -exec convert {} {}.jpg \;grep查找文件内容grep "^\(gcc\|g++\)" # 只保留gcc或g++开头的行(正则表达式!)
input and output flow
默认的输入输出流是终端
[命令] < [输入地址][命令] > [输出地址]最简单的重定向到文件(直接替换原有内容), e.g.cat < hello.txt > hello2.txt[命令2] >> [输出地址](在原来的基础上)追加内容[程序1]|[程序2]|[程序3]管道,像这样连接多个程序
root user
sudo 以superuser的身份执行
如果向/sys下的系统文件写入,必须作为根用户
$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*'
#/sys/class/backlight/thinkpad_screen/brightness
$ cd /sys/class/backlight/thinkpad_screen
$ sudo echo 3 > brightness
#An error occurred while redirecting file 'brightness' open: Permission denied
$ echo 3 | sudo tee brightness
#correct 现在sudo是用于写入了
grammar
foo=bar定义变量,注意没有空格(空格会被识别成参数)!echo "$foo"或echo $foo得打印变量中的内容(转义),echo '$foo'打印原义字符串(无转义)foo=$(pwd)命令替换(command substitution).这里pwd命令的输出($(pwd))被写入foo变量,通过STDIN传递返回值diff <(ls foo) <(ls bar)进程替换(process substitution).<(ls foo)将结果输出到一个临时文件,通过文件传递返回值- 善用一些常用的参数
mcd () { # make a directory and move to it mkdir -p "$1" cd "$1" }函数.
source mcd.sh加载并执行函数$0脚本名;$1到$9即其[参数1]至[参数9]$@所有参数;$#参数个数$?前一个命令的返回值,e.g.执行完上一个命令后,echo $?STDERR可以输出error code(0 fortrue, 1 forfalse)$$当前脚本的进程识别码!!完整的上一条命令,包括参数,e.g. 权限不足执行命令失败时,可以使用sudo !!再尝试一次。$_上一条命令的最后一个参数.如果你正在使用的是交互式 shell,你可以通过按下Esc之后键入.来获取这个值。 - 短路运算符(short-circuiting).与退出码搭配使用,e.g.
false || echo "Oops, fail" true || echo "Will not be printed" true && echo "Things went well" false && echo "Will not be printed" false ; echo "This will always run"||&&代码按顺序从前往后执行,直至满足逻辑(如果第一个已经确定逻辑,之后的不会执行);;代码并列(均会)执行 - 这段脚本遍历参数,使用
grep搜索字符串foobar,如果没有找到,则将其作为注释追加到文件中。#!/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 # 如果模式没有找到,则grep退出状态为 1 # STDOUT and STDERR redirected to NULL are discarded if [[ $? -ne 0 ]]; then #-ne: not equal (\approx !=) echo "File $file does not have any foobar, adding one" echo "# foobar" >> "$file" fi done - 通配(globbing).分别使用
?和*来匹配一个或任意个字符,e.g.rm foo*removes files that start withfoo.花括号{},自动展开一系列子串convert image.{png,jpg} # 会展开为 convert image.png image.jpg cp /path/to/project/{foo,bar,baz}.sh /newpath # 会展开为 cp /path/to/project/foo.sh /path/to/project/bar.sh /path/to/project/baz.sh /newpath mv *{.py,.sh} folder # 会移动所有 *.py 和 *.sh 文件 mkdir foo bar # 排列组合,创建foo/a, foo/b, ... foo/h, bar/a, bar/b, ... bar/h这些文件 touch {foo,bar}/{a..h} #!/usr/local/bin/python或#!/usr/bin/env pythonshebang行告诉内核在shell中也用python解释器.import sys是与shell合调所需要的库一些工具:shelldeck可以详细解释错误;tldr给出例程
command line environment
- 结束进程
^cshell 会发送一个SIGINT信号到进程^\发送SIGQUIT信号kill -TERM <PID>发送更好用的SIGTERM信号- 关闭终端发送SIGHUP信号
- SIGKILL信号不能被进程捕获并且会马上结束该进程,但会有副作用
- 暂停进程
^z发送SIGTSTP信号(terminal stop)fg前台继续bg后台继续jobs列出当前终端会话中尚未完成的全部任务.可以使用 pid 引用任务,使用百分号 + 任务编号选取任务,使用$!选择最近的一个任务- e.g.
nohup sleep 2000 &防止SIGHUP终止后台(&后缀)进程;对已经运行的程序可以使用disown
-
终端多路复用
Action Keys combinations start tmux tmux quit(detach) a session d attach and detach session tmux attach/detach, tmux attach/detach -t [name] list sessions tmux ls create a session tmux new -s [name] to travel among sessions s kill a session tmux kill-session -t [name] Create window c Rename window , Switch to previous window p Switch to next window n Obtain navigable windows list w Kill a window & Split vertically % Split horizontally " visualise pane numbers q Move pane to the left { Move pane to the right } Switch panes layout spacebar navigating ↑ ↓ ← → kill a pane x
git
repository
在一切之前, SSH key配置: https://git-scm.com/downloads
- 在项目目录下执行
git init以创建子目录.git,e.g.git add *.c git add LICENSE git commit -m 'initial version' - 或者
git clone [网址] [自定义名] .gitignore文件中#为注释,用globbing# 忽略所有的 .a 文件 *.a # 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件 !lib.a # 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO /TODO # 忽略任何目录下名为 build 的文件夹 build/ # 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt doc/*.txt # 忽略 doc/ 目录及其所有子目录下的 .pdf 文件 doc/**/*.pdf
status
git status,git status --short或git status -s给出更简洁- new file untracked:
add->staged;staged:commit->unmodified(up-to-date); - existing unmodified: edit->modified,
rm->untracked; modified:stage->staged;commit->unmodified - 如果
add后又修改了? 需要再add后stage&commit,不然保存的是老版本 it commit -a以跳过staged直接全部提交trackedgit rm -f强制删除;git rm --cached [文件名]仅停止跟踪不删除原文件;git rm [目录]/\*.[后缀名],git rm \*[名字结尾]进行批量删除git mv file_from file_tomove可以用来重命名git diff给出gnu diff format,对比当前文件与暂存快照的差异;git diff --stage对比暂存文件与提交文件;git diff --cached看已暂存的变化git log --author='author' --since=2.weeks,git log --pretty=format:"%h %s" --graph看提交历史- 替代第一次提交
$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend取消暂存,建议小心点用
git reset HEAD [已暂存文件];撤销修改git checkout [修改后文件] - tag
branches
每一个type object = blob | tree | commit,其中blob保存文件快照,tree记录目录,commit包含一个指向上次提交对象(父对象)的指针.
Git 的分支本质上是指向提交对象的可变指针.默认分支master指向最后一次提交,特殊指针HEAD指向当前分支,分支独立不干扰,注意用git checkout [分支]切换.
# 新建并切换分支
$ git checkout -b hotfix
# 将hotfix分支合并到master,指针右移(fast-forward)
# <--hotfix<--master
$ git checkout master
$ git merge hotfix
# 删除(抽离)hotfix
git branch -d hotfix
如果合并有文件冲突,可以用git status看,用git mergetool解决