当前位置: 首页 > Linux

计算机教育遗漏的一课-MIT-L5-命令行环境

时间:2023-04-06 07:11:03 Linux

https://missing.csail.mit.edu/https://missing-semester-cn.g...https://www.bilibili.com/video...备注任务控制shell会使用UNIX提供的信号机制进行进程间通信。当进程接收到信号时,它会停止执行,处理信号,并根据信号传递的信息改变其执行。因此,信号是一种软件中断。终止进程参考mansignalkill:向一个进程发送信号;默认为TERMSIGINT:^C;中断程序;终止进程SIGQUIT:^\;退出程序SIGKILL:终止进程;在孤立的子进程中SIGSTOP:暂停进程SIGTSTP:^Z;terminalstopSIGHUP:终端线路挂断;终止进程;将在终端关闭时发送使用nohup避免SIGTERM:signalrequestinggracefulprocessexitTosendthissignal-belowthisPython程序向您展示了捕获信号SIGINT并忽略它的基础知识,这不会停止程序.为了停止程序,我们需要使用SIGQUIT信号。#!/usr/bin/envpythonimportsignal,timedefhandler(signum,time):print("nIgotaSIGINT,butIamnotstopping")signal.signal(signal.SIGINT,handler)i=0while真:time.sleep(.1)print("r{}".format(i),end="")i+=1$pythonsigint.py24^CI得到一个SIGINT,但我不会停止26^CI得到一个SIGINT,butIamnotstopping30^\[1]39913quitpythonsigint.py暂停和后台执行进程使用fg或bg命令恢复暂停的工作。它们分别表示在前台继续或在后台继续。jobs命令列出当前终端会话中所有未完成的作业。可以使用它们的pid(或pgrep来查找pid)来引用这些任务。您也可以使用百分号+作业编号(作业将打印作业编号)来选择作业。如果你想选择最近的任务,你可以使用$!特殊参数。命令中的&后缀可以让命令直接在后台运行,但是此时仍然使用shell的标准输出。使用Ctrl-Z进入后台的进程仍然是终端进程的子进程,一旦终端关闭(发送另一个信号SIGHUP),这些后台进程也将终止。为防止这种情况发生,可以使用nohup(忽略SIGHUP的包装器)运行程序。对于已经在运行的程序,可以使用disown。$sleep1000^Z[1]+18653suspendedsleep1000$nohupsleep2000&[2]18745将输出附加到nohup.out$jobs[1]+suspendedsleep1000[2]-runningnohupsleep2000$bg%1[1]-18653继续睡眠1000$作业[1]-运行睡眠1000[2]+运行nohup睡眠2000$kill-STOP%1[1]+18653暂停(信号)睡眠1000$作业[1]+暂停(信号)sleep1000[2]-运行nohupsleep2000$kill-SIGHUP%1[1]+18653hangupsleep1000$jobs[2]+运行nohupsleep2000$kill-SIGHUP%2$jobs[2]+运行nohupsleep2000$kill%2[2]+18745terminatednohupsleep2000$jobs终端多路复用终端多路复用允许我们分离当前终端会话并在未来重新连接。这极大地改善了您在使用远程设备时的工作流程,避免了对nohup和其他此类技巧的需要。当今最流行的终端多路复用器是tmux。session-每个会话都是一个独立的工作区,包含一个或多个窗口tmux开始一个新会话tmuxnew-sNAME以指定名称开始一个新会话tmuxls列出所有当前会话输入tmuxd(分离),分离当前sessiontmuxa(attach)重新附加上一个会话。也可以使用-t指定特定的session窗口——相当于浏览器中的编辑器或tab,视觉上将一个session分成多个部分c新建一个窗口,使用CloseN跳到第N个窗口,注意每个窗口都有编号p(previous)切换到上一个窗口n(next)切换到下一个窗口,重命名当前窗口w列出当前所有windowpanels-就像vim中的分屏一样,panels允许我们在一个屏幕上显示多个shell"horizo??ntalsplit%verticalsplit切换到指定方向的面板,指的是到键盘上的箭头键z(缩放)切换当前面板的缩放[开始向后滚动屏幕。您可以按空格键开始选择,按回车键复制所选部分在不同的面板布局之间切换扩展阅读:这里有一个tmux快速入门教程,这篇文章更详细,它包含screen命令。你可能想掌握screen命令,因为它默认安装在大多数UNIX系统。别名#colorlssource$(dirname$(gemwhichcolorls))/tab_complete.shaliasls=colorlsaliasl="ls-lh"aliasll="ls-lAh"aliasla="ls-lah"aliashz="history|fzf"aliasmv="mv-i"aliascp="cp-i"aliasmkdir="mkdir-p"#要忽略一个别名,运行它以\ls#为前缀,或者使用unaliasunaliasla#完全禁用一个别名以获得一个别名定义只是用别名调用它l#Willprintl='ls-lh'配置文件(Dotfiles).dotfiles/,由版本控制系统管理,然后通过脚本符号链接到需要的地方。这有以下优点:安装简单:如果您登录到一台新设备,只需几分钟就可以在该设备上应用您的配置;执行:你的工具在任何地方都使用相同的配置同步工作:在一个地方更新配置文件,在其他地方同步更改跟踪:你可能希望在你的程序员生命中持续维护这些配置文件,对于长期项目,版本历史是很重要。一些技巧:if[["$(uname)"=="Linux"]];然后{do_something};fi#使用shell相关配置时,首先检查当前shell类型if[["$SHELL"=="zsh"]];然后{do_something};fi#你也可以为特定的设备配置它if[["$(hostname)"=="myServer"]];然后{do_something};fi#测试~/.aliases是否存在并获取itif[-f~/.aliases];thensource~/.aliasesfiremotedeviceSSH(SecureShell)#connectdevicesshfoo@bar.mit.edusshfoobar@192.168.1.42#如果有配置文件,可以简写sshbar#执行命令#查询本地远程ls的输出sshfoobar@serverls|grepPATTERN#在远程ls查询本地ls的输出|sshfoobar@servergrepPATTERNSSH基于密钥的认证机制使用密码我们只需要向服务器证明客户端持有相应的私钥,而无需泄露其私钥。这样您就可以避免每次使用秘密登录时都要输入密码的麻烦。ssh-keygen-ted25519-C"_your_email@example.com_"#如果您使用的旧系统不支持Ed25519算法,请使用:ssh-keygen-trsa-b4096-C"your_email@example.com”生成id_rsa和id_rsa.pub两个文件(或id_ed25519和id_ed25519.pub),分别是私钥和公钥。私钥相当于您的密码,请务必妥善保管。要检查您是否拥有密钥对的密码并进行验证,您可以运行ssh-keygen-y-f/path/to/key。ssh将查询.ssh/authorized_keys以查看允许哪些用户登录。您可以使用以下命令在此处复制公钥:cat.ssh/id_ed25519.pub|sshfoobar@remote'cat>>~/.ssh/authorized_keys'如果支持ssh-copy-id,您可以使用以下更简单的解决方案:ssh-copy-id-i.ssh/id_ed25519.pubfoobar@remote复制通过SSH复制文件使用ssh复制文件的方法有很多种:ssh+tee,最简单的方法是执行ssh命令,然后通过这样的方法使用标准输入来实现catlocalfile|sshremote_servertee服务器文件。回想一下,tee命令会将标准输出写入文件;scp:当你需要复制大量文件或目录时,使用scp命令会更方便,因为它可以很方便地遍历相关路径。语法如下:scppath/to/local_fileremote_host:path/to/remote_file;rsync改进了scp,可以检测本地和远程文件,防止重复拷贝。它还可以提供一些完善的功能,例如符号链接和权限管理。甚至可以根据--partial标志恢复上传。rsync的语法类似于scp。PortForwardingLocalPortForwardingRemotePortForwarding一个常见的场景是使用本地端口转发,即远程设备上的服务监听一个端口,你想在本地设备上的一个端口上建立连接并转发到远程端口。例如,我们在侦听端口8888的远程服务器上运行JupyterNotebook。然后,要从本地端口9999建立转发,请使用ssh-L9999:localhost:8888foobar@remote_server。这样只需要访问本地localhost:9999即可。SSH配置使用~/.ssh/config文件创建别名,scp、rsync和mosh等命令可以读取此配置并将设置转换为相应的命令行选项。HostvmUserfoobarHostName172.16.174.141Port2222IdentityFile~/.ssh/id_ed25519LocalForward9999localhost:8888#配置文件中也可以使用通配符Host*.mit.eduUserfoobaz服务器端的配置一般放在/etc/ssh/sshd_config.这里可以配置免密码认证,修改shh端口,开启X11转发等,也可以为每个用户单独指定配置。杂项连接到远程服务器的一个常见痛点是遇到由关机、休眠或网络环境变化导致的连接断开。如果连接具有高延迟,它也会很烦人。Mosh(又名移动shell)通过允许连接漫游、间歇性连接和智能本地回显改进了ssh。有时候把远程文件夹挂载到本地更方便,sshfs可以把远程服务器上的文件夹挂载到本地,然后就可以使用本地编辑器了。Shell&Frameworks常用Shell:bashzshfish常用Shell框架:oh-my-zshprezto终端仿真器一些经典仿真器:xtermGNOMETerminalKonsoleXfceTerminalurxvtTerminator一些新兴仿真器(通常性能更好,比如下面两个带GPU加速的):Alacrittykitty课后练习任务控制练习1$sleep1000^Z[1]+689suspendedsleep1000$sleep2000^Z[2]+697suspendedsleep2000$jobs[1]-suspendedsleep1000[2]+suspendedsleep2000$bg%1[1]-689继续睡眠1000$jobs[1]-运行睡眠1000[2]+暂停睡眠2000$pgrep-af"sleep1"689sleep1000$pkill-f"sleep1"[1]-689终止睡眠1000$jobs[2]+suspendedsleep2000$pkill-f"sleep2"$jobs[2]+suspendedsleep2000$pkill-9-f"sleep2"[2]+697killedsleep查看mankillfor2000$jobs,默认发送的信号是TERM。-9等价于-SIGKILL或-KILL习题2$sleep10&[1]1121$pgrepsleep|等待;ls[1]+1121donesleep10这里没什么可显示的$pidwait(){wait$1echo"done"eval$2}$sleep10&[1]1420$pidwait1420"ls"[1]+1420donesleep10doneNothing在这里展示