linux 相关-基本命令
linux 相关
linux 命令 option 通用格式¶
- POSIX-styled 的 option 由一个 dash 和一个字符组成
- GNU-style 的 long option 由两个 dash 和一个关键字 (keyword) 组成
- 关键字能被缩写,只要足够区分不同关键字
- 如果关键字需要一个参数 (argument),可以在关键字后紧跟一个等号=,然后紧跟着关键字的值。或者将关键字和值用空白字符 (whitespace) 分隔开。
- 如果关键字被多次赋值,则以最后一次的为准
man wget
- 解析参数方法
- GUN getopt
- 是否支持合并
- 是否支持选项放在参数后面
- 由于支持选项放在参数后面,因此还有个分隔符(
--)用于表示 option 结束。分隔符后都是参数。- Since the options can be specified after the arguments, you may terminate them with
--. So the following will try to download URL -x, reporting failure to log:wget -o log -- -x - 如何删除/创建一个名字为
-IsADir的文件夹,rm -r -- '-IsADir'
- Since the options can be specified after the arguments, you may terminate them with
- 由于支持选项放在参数后面,因此还有个分隔符(
vim¶
基本¶
# insert mode
i, o, O
# 光标移动
i, j, k, l
gg, G
w, W, b, B # move word
# 复制粘贴
yy, p
dw # 剪切单词
/pattern # 查找
n
添加 tab¶
- ctrl-v 进入 visual block 模式(如果使用 windows terminal,ctrl-v 被设置为粘贴会导致无法进入),或者 shift-v 进入 visual line 模式。
- "shift + dot",被选中的行便会 tab 一次,重复"dot"可以 tab 任意次
- 或者
:进入命令模式,>往右 tab,<往左 tab
- 或者
也可以直接使用命令模式,以下命令将 1-5 行向右 tab 2 次
高级¶
光标移动
H, M, L # top, middle, bottom of screen
fx # jump to next occurrence of character x
} # jump to next paragraph (or function/block, when editing code)
{
zz # center cursor on screen
Ctrl + b - move back one full screen
Ctrl + f - move forward one full screen
Ctrl + d - move forward 1/2 a screen
Ctrl + u - move back 1/2 a screen
查找替换
- %表示整个文件 range(否则只会替换第一次匹配)
执行 shell 命令¶
:!{cmd}
:!ls -alh # 查看当前目录下文件
:w !{cmd} # buffer | cmd
:%!{cmd} # buffer | cmd | buffer
:%!grep xxx # 过滤文件内容,保留匹配的部分
忘记 sudo¶
write with sudoHow does the vim "write with sudo" trick work? - Stack Overflow
- w 命令完整格式:
:[range]w[rite] [++opt] !{cmd}- 表示执行 cmd,并将当前编辑缓冲区内容作为 cmd 输入
- 例子
:w !grep xxx,grep 文件内容
%:这里表示文件名- 因此上述命令将 buffer 内容 pipe 给 sudo 执行的 tee 命令,tee 命令将 stdin 输出到当前文件和 stdout,从而实现对文件的写入。
为上述命令设置别名 w!!
" Allow saving of files as sudo when I forgot to start vim using sudo.
cmap w!! w !sudo tee > /dev/null %
编辑二进制文件¶
binary file - How can I use Vim as a hex editor? - Vi and Vim Stack Exchange
:%!xxd
:%!{cmd}有点像 loopback,把当前缓冲区 pipe 给 cmd 然后再将其输出写回到缓冲区。- xxd 输入二进制输出 hex 文本
:%!xxd -r
- xxd -r 输入 hex 文本输出二进制
:wq
写回文件
配置文件¶
自定义命令:key bindings - Is there a command to enter Visual Block mode? - Vi and Vim Stack Exchange
cp 注意点¶
- cp file1 file2 ... dir
- cp -r dir1 dir2
- 如果 dir2 存在,则将 dir1 复制到 dir2 内,即 dir2/dir1
- 如果 dir2 不存在,则将 dir1 复制为 dir2
- cp dir1/* dir2
- 将 dir1 下所有文件复制到 dir2 内,如果 dir1 存在目录,则应添加-r 选项
sed, awk, grep¶
这些命令要深入研究的话,内容都很多。比如 awk 可以算是一种用于处理文本的解释型编程语言。因此,比较好的方法是从需求出发,看看在 linux 下一般有哪些文字处理的需求,再看使用哪种工具比较方便简单。
命令格式¶
grep [option] pattern file
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
awk [options] 'pattern {action}' [file]
正则表达式¶
基本正则表达式(Basic Regular Expressions)和扩展正则表达式(Extended Regular Expressions)是两种 POSIX 正则表达式风格。
BRE 可能是如今最老的正则风格了,对于部分特殊字符(如
+,?,|,{)需要加上转义符\才能表达其特殊含义。ERE 与如今的现代正则风格较为一致,相比 BRE,上述特殊字符默认发挥特殊作用,加上
\之后表达普通含义。
sed¶
-
修改文件中某部分内容。一般可以使用正则表达式,匹配到对应位置,然后进行修改。
//将文件中所有的 key=xxx,修改为 key=${val} //-i 表示在原文件上修改,去掉后会将结果输出到命令行 // 这里还用到了字符串拼接语法,将两个字符串写到一起就会拼接。单引号内不能进行转义,因此为了使用变量 val 需要使用双引号。 sed -i 's/key=[0-9]+/'"key=${val}/g"sed 其它命令: - s 替换 - d 删除 -
c\text:选定行改成新文本text- 在实际使用中,如果新文本需要跨多行,每一行的末尾(除了最后一行)通常需要加上反斜线(\) - a 当前行下插入文本 - i 当前行上插入文本
地址范围匹配模式¶
sed /xxx/,/yyy/{ commands }
- 这里使用了 here document
- bash -s 才可以指令这样的多行脚本
ssh $REMOTE "bash -s" <<EOF
sed -i "/$WG_PUB_KEY/,/^config/{
s/option endpoint_port.*/option endpoint_port '$PUBLIC_PORT'/
s/option endpoint_host.*/option endpoint_host '$PUBLIC_IP'/
}" "/etc/config/network"
#wg set $WG_IF peer $WG_PUB_KEY endpoint $PUBLIC_IP:$PUBLIC_PORT
ifconfig $WG_IF down && ifup $WG_IF
EOF
多行命令¶
sed -i -e '/^port/c #port: 7890' -e '/^socks-port/c #socks-port: 7891' -e 's/^allow-lan.*/allow-lan: true/' -e '/^allow-lan/i mixed-port: 11223' glados.yaml
更多例子¶
$表示最后一行a表示在指定行后面添加内容
r /tmp/grub.new:读取文件内容并插入指定行后
awk¶
其它¶
head, tail¶
tail # 输出最后10行
tail -n k # 输出最后k行
tail -n +k # 输出从第k行(1开始)的所有行
head # 输出前10行
head -n k # 输出前k行
head -n -k # 输出除结尾k行后的所有行
xargs¶
从标准输入读取 items(使用 blank 或者 newline 分隔),然后执行 command(默认/bin/echo)。使用 -n 决定每次传递多少 iterm。-p 可以看到执行的具体命令,并决定是否执行。
iterm 会接在 command 结尾,如果想要指定位置,需要指定 replace str -I{}
l "/mnt/Disk2/BT/downloads/Video/TV_anime/" | grep Juju | cut -d ' ' -f 9- | xargs -I {} rm -r "/mnt/Disk2/BT/downloads/Video/TV_anime/{}"
不过 -I 隐含了 -L 1,因此输入会按照换行分隔,并且一次输入一行。(xargs 并不支持多个 replace str)
--delimiter=delim, -d delim:指定输入的分隔符,单个字符,可以是 C 风格的字符,如转移字符,字符八进制表示等。
tar¶
- -C : change the current directory
.: add the entire current directory
| 压缩算法 | 扩展名 | 压缩选项 | 打包/压缩 (C) | 解压/解包 (X) |
| None | .tar | 无 | tar -cvf 文件名.tar 目录/文件 | tar -xvf 文件名.tar |
| Gzip | .tar.gz 或 .tgz | -z | tar -zcvf 文件名.tar.gz 目录/文件 | tar -zxvf 文件名.tar.gz |
| Bzip2 | .tar.bz2 或 .tbz | -j | tar -jcvf 文件名.tar.bz2 目录/文件 | tar -jxvf 文件名.tar.bz2 |
| Zstd | .tar.zst | -I zstd | tar -I zstd -cvf 文件名.tar.zst 目录/文件 | tar -I zstd -xvf 文件名.tar.zst |
| xz | .tar.xz 或 .txz | -J | tar -Jcvf 文件名.tar.xz 目录/文件 | tar -Jxvf 文件名.tar.xz |
-I选项zstd -9xz -9bzip2 -9gzip -9
-c:写到标准输出-d:解压-0..9:压缩级别- xz,zstd
-k:保留原始输入-vv
zip¶
unzip file.zip # 解药到当前目录
unzip file.zip -d /path/to/dir
unzip -l file.zip # 列出文件内容
zip -r file.zip /path/to/dir # 将目录压缩,包含顶层目录
zip -r file.zip ./ # 将当前目录压缩,不包含顶层目录
zip -r file.zip ./* # 将当前目录压缩,不包含点文件,如 .git
cut¶
grep¶
-o: only print matched part
iAddr=`ip addr show dev $interface |grep "inet.*" |head -n1 |grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\/[0-9]\{1,2\}'`
查找一个目录中的所有文件
coreutils¶
env¶
run command in a modifed environment
env invocation (GNU Coreutils 9.5)
-i---ignore-environment- Start with an empty environment, ignoring the inherited environment.
-C--chdir=dir- Change the working directory to dir before invoking command.
另外的作用就是,用于脚本文件第一行,用于找到执行文件执行
When a script’s interpreter is in a non-standard location in the
PATHenvironment variable, it is recommended to useenvon the first line of the script to find the executable and run it:
Networking¶
curl¶
- -O, --remote-name
- Write output to a local file named like the remote file we get. (Only the file part of the remote file is used, the path is cut off.)
- The file will be saved in the current working directory
-L:- follow 重定向
curl -OL 可以得到正确的名字,而 wget 得到错误的名字,wget --content-dispo 可以得到正确的名字
组合例子¶
查看硬盘读写数据量¶
- awk + xargs 的经典组合
- xargs 期望接收一个程序,因此使用 sh -c 执行多个命令
root@nas-pve ➜ ~ l /dev/disk/by-id |grep ata |grep -v part |grep -v 1CH166 | awk '{print $9}' | xargs -I {} sh -c "echo {} && smartctl -a /dev/disk/by-id/{} |grep Total_LBA"
ata-ST3000DM001-1ER166_Z503YWZM
241 Total_LBAs_Written 0x0000 100 253 000 Old_age Offline - 147299474287
242 Total_LBAs_Read 0x0000 100 253 000 Old_age Offline - 221070852226
ata-ST3000DM001-1ER166_Z503Z1KS
241 Total_LBAs_Written 0x0000 100 253 000 Old_age Offline - 133796995265
242 Total_LBAs_Read 0x0000 100 253 000 Old_age Offline - 4042769841615
ata-ST3000DM008-2DM166_Z505BZTC
241 Total_LBAs_Written 0x0000 100 253 000 Old_age Offline - 132181061457
242 Total_LBAs_Read 0x0000 100 253 000 Old_age Offline - 2421892057898
ata-ST3000DM008-2DM166_Z505BZYA
241 Total_LBAs_Written 0x0000 100 253 000 Old_age Offline - 129431883253
242 Total_LBAs_Read 0x0000 100 253 000 Old_age Offline - 2487408613390
ata-ST4000VX000-2AG166_ZGY9RGSW
241 Total_LBAs_Written 0x0000 100 253 000 Old_age Offline - 51708537191
242 Total_LBAs_Read 0x0000 100 253 000 Old_age Offline - 290782158413
ata-WDC_WD20EJRX-89AKWY0_WD-WX12D415NAFF
ata-WDC_WD20EJRX-89G3VY0_WD-WCC4M0KDNUE5