【Missing Semester L5】命令行环境Command-line Environment(进程控制、tmux、别名、配置、SSH)

lecture note
这节的主要目的是学会更好的提升使用shell时的工作流控制,比如如何控制多个进程,还有其他一些提升工作效率的工具,比如别名、多终端、文件配置等,还有远程登录。

Job Control

通常,想要结束一个正在运行的job可以直接按Ctrl C,但是实际是如何终止的,以及为什么有时候不起作用呢?

结束进程

Unix是通过信号来沟通的(Signal),进程收到信号后会先处理信号信息,并有可能基于信号的信息来改变执行状态,因此信号也是Software interrupt。
当在shell按Ctrl C的时候会发送SIGINT 信号给当前进程。可以通过编程让程序收到这个信号的时候还是不停下。
也可以用 kill来结束,发送的是SIGTERM

暂停和后台运行

SIGSTOP可以暂停一个进程,通过按Ctrl Z,之后可以用fgbg来让被暂停的进程在前台或后台继续运行。
jobs命令会列出当前运行中的程序,可以通过PID来看,也可以用%加jobnumber,最后一个后台运行的可以用 $!
命令后跟&可以让命令后台运行。把正在运行的程序放到后台去运行,可以Ctrl Z + bg
在这里插入图片描述
不过即使后台运行,这个进程仍然是当前终端的子进程,把当前小黑窗关了这些进程都会被关掉,除非用nohup,或者对已经开始了的进程用disown,也可以用下一节讲的terminal multiplexer
一些例子

$ sleep 1000
^Z
[1]  + 18653 suspended  sleep 1000

$ nohup sleep 2000 &
[2] 18745
appending output to nohup.out

$ jobs
[1]  + suspended  sleep 1000
[2]  - running    nohup sleep 2000

$ bg %1
[1]  - 18653 continued  sleep 1000

$ jobs
[1]  - running    sleep 1000
[2]  + running    nohup sleep 2000

$ kill -STOP %1
[1]  + 18653 suspended (signal)  sleep 1000

$ jobs
[1]  + suspended (signal)  sleep 1000
[2]  - running    nohup sleep 2000

$ kill -SIGHUP %1
[1]  + 18653 hangup     sleep 1000

$ jobs
[2]  + running    nohup sleep 2000

$ kill -SIGHUP %2

$ jobs
[2]  + running    nohup sleep 2000

$ kill %2
[2]  + 18745 terminated  nohup sleep 2000

$ jobs

信号SIGKILL是不能被进程捕获的,会直接结束进程。不过会有些副作用,比如留下孤儿进程。
可以通过man kill或者kill -l看更多信号内容

Terminal Multiplexers

tmux终端多路复用。
可以用tmux来打开多个终端shell进行切换控制,并且可以在关闭某个终端后重新回去。尤其是和远程连接一起用的时候,不再需要使用nohup
当前最受欢迎的终端多路复用器就是tmux,可以进行key bindings,并且高度可配置化,可以创建多个tabs和panes并且快速的进行来回切换。
安装:

sudo apt-get install tmux #ubuntu
brew install tmux #Mac

tmux的快捷键一般是Ctrl B+某个key。也就是按下Ctrl B,然后松开,然后再按另一个key。
tmux主要有三个概念:

Sessions

有多个windows的独立的工作空间。

  • tmux命令会打开一个新的session
  • tmux new -s Name打开一个新的Name的session
  • tmux ls列出当前的Sessions
  • 在当前的session下,按Ctrl B松开再按d可以离开当前的session
  • tmux a可以回到最后一个session
  • 重新回到某个session可以 tmux attach -t <number>/name

Windows

类似于editor或者chrome的tabs,多个windows可以看成一个sessions的不同部分。

  • Ctrl b c创建一个新的window,退出的话可以直接按Ctrl d
  • Ctrl b N去第n个窗口
  • Ctrl b p去前一个窗口
  • Ctrl b n 去下一个窗口 加数字精准跳跃,从0开始编号
  • Ctrl b ,重命名当前窗口
  • Ctrl b w列出当前窗口,q退出

Panes

类似vim 的splits,可以有多个视图来看

  • Ctrl b "水平分
  • Ctrl b %垂直分
  • Ctrl b 方向键在不同的pane之间移动
  • Ctrl b z切换当前pane的zoom(放大成一个 或缩回原来的)
  • Ctrl b [可以滚动,然后按空格开始一个selection,然后enter进行复制
  • Ctrl b 空格可以来回变化panes的布局
  • 输入exit或按Ctrl d可以关闭Pane

更多关于tmux的内容可以看quick start,以及更为详细的这里

别名

每次写很长的命令带各种参数是很麻烦的,为此大部分shell都是支持别名的aliases.shell会自动把别名替换为完整的命令。

alias alias_name="command_to_alias arg1 arg2"

注意这里=左右是没有空格
有很多方便的

# Make shorthands for common flags
alias ll="ls -lh"

# Save a lot of typing for common commands
alias gs="git status"
alias gc="git commit"
alias v="vim"

# Save you from mistyping
alias sl=ls

# Overwrite existing commands for better defaults
alias mv="mv -i"           # -i prompts before overwrite
alias mkdir="mkdir -p"     # -p make parent dirs as needed
alias df="df -h"           # -h prints human readable format

# Alias can be composed
alias la="ls -A"
alias lla="la -l"

# To ignore an alias run it prepended with \
\ls
# Or disable an alias altogether with unalias
unalias la

# To get an alias definition just call it with alias
alias ll
# Will print ll='ls -lh'

不过这些配置是暂时的,不是永久的。想要一直有得编辑到.bashrc或.zshrc里,下一节会讲到

dotfiles

很多程序都有点开头的文件作为配置文件,以.开头,通常ls会忽略这些隐藏文件。
Shell也有,会从中读取复杂的配置。shell启动脚本讲解可以看下这里
对bash而言,编辑.bashrc or .bash_profile通常可以添加启动配置,比如上面提到的alias别名,也可以加上PATH变量的修改。很多程序都要求在PATH上加上一行以便找到程序位置。
还有一些其他可以配置的dotfiles:

  • bash - ~/.bashrc, ~/.bash_profile
  • git - ~/.gitconfig
  • vim - ~/.vimrc and the ~/.vim folder
  • ssh - ~/.ssh/config
  • tmux - ~/.tmux.conf
    更好的管理dotfiles的方式:各自在自己的文件夹下,有版本控制,然后链接到合适的位置。这样的好处是在新机器上很容易安装,更便携,可以保持同步,还可以进行版本控制。
    可以看看github上其他人的配置,比如dotfiles github,比如最受欢迎的this,不过最好不要盲目的一键配置。
    有些配置可能不想搞的每台机器都一样(有时候因为系统不一样也无法生效),可以用条件来控制这些配置,比如
if [[ "$(uname)" == "Linux" ]]; then {do_something}; fi

# Check before using shell-specific features
if [[ "$SHELL" == "zsh" ]]; then {do_something}; fi

# You can also make it machine-specific
if [[ "$(hostname)" == "myServer" ]]; then {do_something}; fi

如果支持的话,也可以用includes来导入本地的配置文件

[include]
    path = ~/.gitconfig_local

remote machines

远程ssh登录一台机器:
ssh foo@bar.mit.edu
也可以直接运行命令,类似
ssh foobar@server ls | grep PATTERN,本地grep远程ls的内容
SSH keys(一般是在~/.ssh/id_rsa内)可以让你不用每次都输入密码
生成一对密钥可以使用:
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519
可以加上一个密码口令,防止其他有你私玥的人登录,可以通过SSH-agent
检查你github的密钥对是否用了passphrase可以用ssh-keygen -y -f /path/to/key
ssh会检查.ssh/authorized_keys来决定让哪个客户机登录。

传文件

远程传递文件可以通过以下:

  • ssh+tee比如cat localfile | ssh remote_server tee serverfile
  • scp 比如scp path/to/local_file remote_host:path/to/remote_file
  • rsync类似scp,不过可以避免传重复的文件

port forwarding

关于prot forwarding,可以看下stack Overflow
举个例子,在远程机器上运行了jupyter notebook听的是8888端口,想要forward到本地机器9999上,可以执行ssh -L 9999:localhost:8888 foobar@remote_server,然后在本地localhost:9999就行

ssh 配置

常见的别名处理:

alias my_server="ssh -i ~/.id_ed25519 --port 2222 -L 9999:localhost:8888 foobar@remote_server

不过更好的方式是用~/.ssh/config

Host vm
    User foobar
    HostName 172.16.174.141
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    LocalForward 9999 localhost:8888

# Configs can also take wildcards
Host *.mit.edu
    User foobaz

这个虽然也是dotfie,不过最好还是不要公开,容易被攻击。
远程端的配置是/etc/ssh/sshd_config

其他

SSH常遇到的一个问题就是老因为各种原因断开,MOSH
有时候也需要Mount remote folder,可以借助sshfs

Shells & Frameworks

除了bash之外还有其他的shell,非常出名的是zsh
framework也可以很好的提升shell,比较知名的有prezto on my zsh,还有一些小的,比如zsh的各种plugins. fishshell本身就包含了一些用户友好的特性。
不过这些额外的代码有时候会slow down the shell

terminal emulators终端模拟器

终端模拟器及其设置也很值得注意,一些比较可以看这里
可能需要配置一些:

  • 字体 Font choice
  • 颜色主题Color Scheme
  • 快捷键
  • Tab/Pane support
  • Scrollback configuration
  • Performance (some newer terminals like Alacritty or kitty offer GPU acceleration).

练习

job control

1、用ps aux | grep可以看到pid,然后去kill,不过还有更好的方法。启动一个sleep 10000job,然后用Ctrl Z暂停,用bg继续,然后用pgrep找到pid,然后用pkill,不需要输入Pid就可以杀死进程(用上-af)

pgrep -f sleep
pkill -f sleep

2、写个脚本,实现等待一个PID进程结束之后再运行。单纯的wait只能在一个bash离起作用,试试用kill -0,如果进程不存在,这个指令会返回非零值。后台运行sleep 60 &,等待运行完后进行ls。
尝试写一下:

echo "the pid is $1"
while;do
kill -0 $1
if [[ $? -ne 0 ]]; then
#   echo "not zero"
sleep
else
   echo "zero"
   ls
fi
break
done

Terminal multiplexer

完成这个教程,并且根据以下步骤学习如何进行基础的配置
教程博主对tmux的解释:让你在一个终端里打开多个窗口或分屏,每个pane里都运行一个单独的终端实例。如果不detach的话,会保留到机器重启。
各种操作都是通过prefix key + 命令key
配置教程里可以把Ctrl b换成Ctrl a方便很多

aliases

1、创建一个别名dc指向cd,以应对错误输入的情况
alias dc="cd"
2、Run history | awk '{$1="";print substr($0,2)}' | sort | uniq -c | sort -n | tail -n 10 to get your top 10 most used commands and consider writing shorter aliases for them. Note: this works for Bash; if you’re using ZSH, use history 1 instead of just history.

Dotfiles

Let’s get you up to speed with dotfiles.

1.Create a folder for your dotfiles and set up version control.
2.Add a configuration for at least one program, e.g. your shell, with some customization (to start off, it can be something as simple as customizing your shell prompt by setting $PS1).
3.Set up a method to install your dotfiles quickly (and without manual effort) on a new machine. This can be as simple as a shell script that calls ln -s for each file, or you could use a specialized utility.
4.Test your installation script on a fresh virtual machine.
5.Migrate all of your current tool configurations to your dotfiles repository.
6.Publish your dotfiles on GitHub.

remote machines

TODO

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值