Linux命令行环境

本文介绍了Linux中进程的控制,包括结束、暂停与后台执行,重点讲解了终端多路复用器tmux的使用,如新建、管理会话、窗口和面板操作,以及如何通过SSH进行远程命令执行和文件传输,强调了配置文件的管理和可移植性。
摘要由CSDN通过智能技术生成


任务控制

shell使用UNIX提供的信号机制执行进程间的通信,进程收到信号时,它会停止执行,先处理完信号,并基于信号的信息可能改变自己的执行行为。

结束进程

当一个进程运行时,我们输入ctrl-C,shell会发送一个SIGINT信号给进程,进程收到这个信号后,将会停止执行。
结束进程的信号包括SIGINT,SIGQUIT,SIGTERM,SIGKILL四者区别为:

信号作用
SIGINT程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。
SIGQUIT和SIGINT类似, 但由QUIT字符(通常是Ctrl-\)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。
SIGTERM程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省会产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。
SIGKILL程序立即结束信号,这个信号无法被捕获与忽略,可能导致孤儿进程(父进程结束,子进程仍然存在)

暂停和后台执行进程

信号SIGSTOP信号会暂停进程,或者在终端中输入Ctrl-Z,终端会发送SIGTSTP,功能与SIGSTOP相同,都会进入暂停模式。
我们可以使用fg或bg命令,重新开始暂停的进程,让它在前台或者后台重新运行起来。
jobs 命令会列出当前终端会话中尚未完成的全部任务。可以使用 pid 引用这些任务(也可以用 pgrep 找出 pid)。更加符合直觉的操作是可以使用百分号 + 任务编号(jobs 会打印任务编号)来选取该任务。如果要选择最近的一个任务,可以使用 $! 这一特殊参数。
命令之后+&后缀可以让命令直接在后台运行,但是如果此刻程序有输出的话,还是会打印出来,这时候可以用输出重定向,来将输出重定向到文件中。
让已经运行的程序,通过ctrl-Z再加bg的方式也可以转到后台运行。
一般来说,后台进程仍然属于终端的子进程,当终端窗口被关闭后,(会发送另外一个信号SIGHUP)后台进程也会停止,为了防止这种情况发生,可以使用 nohup (一个用来忽略 SIGHUP 的封装) 来运行程序。针对已经运行的程序,可以使用disown 。
下面来展示这些概念:

(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ nohup sleep 2000 &
[2] 25955
nohup: ignoring input and appending output to 'nohup.out'
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Running                 nohup sleep 2000 &
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ bg %1
[1]+ sleep 1000 &
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs
[1]-  Running                 sleep 1000 &
[2]+  Running                 nohup sleep 2000 &
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ kill -STOP %1

[1]+  Stopped                 sleep 1000
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Running                 nohup sleep 2000 &
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ kill -SIGHUP %1
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs
[1]-  Hangup                  sleep 1000
[2]+  Running                 nohup sleep 2000 &
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs
[2]+  Running                 nohup sleep 2000 &
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ kill %2
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs
[2]+  Terminated              nohup sleep 2000
(base) chentaowu@chentaowu-MS-7C88:~/chentaowu/learning_linux/lesson5_terminate_env$ jobs

终端多路复用

终端多路复用可以支持我们在命令行下执行多个任务。比如在编辑文本的同时,执行另一个程序。
现在最流行的终端多路复用技术是tmux,tmux的快捷键大多数都是 x的方式实现,即先按下Ctrl+b,再按下x。
tmux中对象的继承结构如下:

-会话

每个会话都是一个独立的工作区,其中包含一个或多个窗口

tmux 开始一个新的会话

在这里插入图片描述

tmux new -s NAME 以指定名称开始一个新的会话

比如tmux new -s geraltwu
在这里插入图片描述

tmux ls 列出当前所有会话在这里插入图片描述
在 tmux 中输入 d ,将当前会话分离

在这里插入图片描述

tmux a 重新连接最后一个会话。您也可以通过 -t 来指定具体的会话

比如输入指令:

tmux a -t 1

将出现在这里插入图片描述

-窗口

相当于编辑器或是浏览器中的标签页,从视觉上将一个会话分割为多个部分

创建与关闭窗口

<C-b> c 创建一个新的窗口,使用 关闭
创建新窗口
在这里插入图片描述
关闭当前窗口
在这里插入图片描述

窗口切换

<C-b> N 跳转到第 N 个窗口,注意每个窗口都是有编号的
<C-b> p 切换到前一个窗口
<C-b> n 切换到下一个窗口

窗口重命名

<C-b> , 重命名当前窗口
在这里插入图片描述
由bash改成geralt
在这里插入图片描述
在这里插入图片描述
<C-b> w 列出当前所有窗口
在这里插入图片描述
这时可以通过黄色光标自由选择对应的窗口,按下回车键后,将会自动切换到选中的窗口。

面板

像 vim 中的分屏一样,面板使我们可以在一个屏幕里显示多个 shell
<C-b> " 水平分割
在这里插入图片描述
<C-b> % 垂直分割
在这里插入图片描述
<C-b> <方向> 切换到指定方向的面板,<方向> 指的是键盘上的方向键
<C-b> z 切换当前面板的缩放
这个命令会将被选中的分割后的窗口放大,再输入一次以上命令,又会缩回到原来的分割窗口。
<C-b> [ 开始往回卷动屏幕。您可以按下空格键来开始选择,回车键复制选中的部分
<C-b> <空格> 在不同的面板排布间切换

别名

shell中支持利用别名alias,来替换长命令。在bash中别名的语法如下:

alias alias_name="command_to_alias arg1 arg2"

注意, =两边是没有空格的,因为 alias 是一个 shell 命令,它只接受一个参数。
别名有许多方便的特性,比如:

# 创建常用命令的缩写
alias ll="ls -lh"

# 能够少输入很多
alias gs="git status"
alias gc="git commit"
alias v="vim"

# 手误打错命令也没关系
alias sl=ls

# 重新定义一些命令行的默认行为
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 la="ls -A"
alias lla="la -l"

# 在忽略某个别名
\ls
# 或者禁用别名
unalias la

# 获取别名的定义
alias ll
# 会打印 ll='ls -lh'

值得注意的是,在默认情况下 shell 并不会保存别名。为了让别名持续生效,您需要将配置放进 shell 的启动文件里,像是.bashrc 或 .zshrc

配置文件(Dotfiles)

shell的配置与很多程序的配置一样,都是通过纯文本格式的被称作点文件的配置文件来完成的(之所以称为点文件,是因为它们的文件名以 . 开头,例如 ~/.vimrc。也正因为此,它们默认是隐藏文件,ls并不会显示它们)。
shell在启动的时候会读取很多文件以加载配置。
对于 bash来说,在大多数系统下,可以通过编辑 .bashrc 或 .bash_profile 来进行配置。在文件中可以添加需要在启动时执行的命令,例如上文我们讲到过的别名,或者环境变量。
实际上,很多程序都要求在 shell 的配置文件中包含一行类似 export PATH=“$PATH:/path/to/program/bin” 的命令,这样才能确保这些程序能够被 shell 找到。

还有一些其他的工具也可以通过点文件进行配置:

bash - ~/.bashrc, ~/.bash_profile
git - ~/.gitconfig
vim - ~/.vimrc 和 ~/.vim 目录
ssh - ~/.ssh/config
tmux - ~/.tmux.conf
我们应该如何管理这些配置文件呢,它们应该在它们的文件夹下,并使用版本控制系统进行管理,然后通过脚本将其 符号链接 到需要的地方。这么做有如下好处:

安装简单: 如果登录了一台新的设备,在这台设备上应用的配置只需要几分钟的时间;
可以执行: 您的工具在任何地方都以相同的配置工作
同步: 在一处更新配置文件,可以同步到其他所有地方
变更追踪: 可能要在整个程序员生涯中持续维护这些配置文件,而对于长期项目而言,版本历史是非常重要的。

可移植性

有一些技巧可以让配置文件在不同的设备上生效。
如果配置文件支持if语句,以借助它针对不同的设备编写不同的配置:

if [[ "$(uname)" == "Linux" ]]; then {do_something}; fi

# 使用和 shell 相关的配置时先检查当前 shell 类型
if [[ "$SHELL" == "zsh" ]]; then {do_something}; fi

# 您也可以针对特定的设备进行配置
if [[ "$(hostname)" == "myServer" ]]; then {do_something}; fi

如果配置文件支持 include 功能,例如:~/.gitconfig 可以这样编写:

[include]
    path = ~/.gitconfig_local

然后我们可以在日常使用的设备上创建配置文件 ~/.gitconfig_local 来包含与该设备相关的特定配置。
如果希望在不同的程序之间共享某些配置,该方法也适用。例如,如果想要在 bash 和 zsh 中同时启用一些别名,可以把它们写在 .aliases 里,然后在这两个 shell 里应用。

远程设备

一般使用安全SHELL——SSH来连接远程设备,可以通过以下指令连接远程设备:

ssh user_name@url或者ssh user_name@ip

我们可以通过这样的指令来连接远程设备。

执行命令

ssh 的一个经常被忽视的特性是它可以直接远程执行命令。 ssh foobar@server ls 可以直接在用foobar的命令下执行 ls 命令。 想要配合管道来使用也可以, ssh foobar@server ls | grep PATTERN 会在本地查询远端 ls 的输出而 ls | ssh foobar@server grep PATTERN 会在远端对本地 ls 输出的结果进行查询。

SSH密钥

基于密钥的验证机制使用了密码学中的公钥,我们只需要向服务器证明客户端持有对应的私钥,而不需要公开其私钥。这样您就可以避免每次登录都输入密码的麻烦了秘密就可以登录。不过,私钥(通常是 ~/.ssh/id_rsa 或者 ~/.ssh/id_ed25519) 等效于您的密码,所以一定要好好保存它。

密钥生成

使用 ssh-keygen 命令可以生成一对密钥:

ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519

您可以为密钥设置密码,防止有人持有您的私钥并使用它访问您的服务器。您可以使用 ssh-agent 或 gpg-agent ,这样就不需要每次都输入该密码了。

如果您曾经配置过使用 SSH 密钥推送到 GitHub,那么可能您已经完成了这里 介绍的这些步骤,并且已经有了一个可用的密钥对。要检查您是否持有密码并验证它,您可以运行 ssh-keygen -y -f /path/to/key.

基于密钥的认证机制

ssh 会查询 .ssh/authorized_keys 来确认那些用户可以被允许登录。您可以通过下面的命令将一个公钥拷贝到这里:

cat .ssh/id_ed25519 | ssh foobar@remote 'cat >> ~/.ssh/authorized_keys'

如果支持 ssh-copy-id 的话,可以使用下面这种更简单的解决方案:

ssh-copy-id -i .ssh/id_ed25519.pub foobar@remote

通过SSH复制文件

使用 ssh 复制文件有很多方法:

ssh+tee, 最简单的方法是执行 ssh 命令,然后通过这样的方法利用标准输入实现 cat localfile | ssh remote_server tee serverfile。回忆一下,tee 命令会将标准输出写入到一个文件;
scp :当需要拷贝大量的文件或目录时,使用scp 命令则更加方便,因为它可以方便的遍历相关路径。语法如下:scp path/to/local_file remote_host:path/to/remote_file;
rsync 对 scp 进行了改进,它可以检测本地和远端的文件以防止重复拷贝。它还可以提供一些诸如符号连接、权限管理等精心打磨的功能。甚至还可以基于 --partial标记实现断点续传。rsync 的语法和scp类似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值