使用 Shell 的一些总结

2020/11/13 Shell

推荐阅读

shell中的特殊符号
    https://www.cnblogs.com/kevingrace/p/5896386.html

执行结果赋值变量

倒引号 “ ` “ ,相当于$(),表示命令替换,将里面命令执行结果传给变量参数。

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ a=`ls`

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ b=$(ls)

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ echo $a
1.py command.jar command.sh desktop.ini phpstudy.lnk Telegram.lnk 彩金战旗.docx 飞书.lnk 微信开发者工具.lnk 为知笔记.lnk

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ echo $b
1.py command.jar command.sh desktop.ini phpstudy.lnk Telegram.lnk 彩金战旗.docx 飞书.lnk 微信开发者工具.lnk 为知笔记.lnk

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ cat 1.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
x = sys.argv
for  i in range(int(x[1]),int(x[2])):
    print (i)

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ cat command.sh
#!/usr/bin/env bash
a=`python 1.py ${@:1}`
echo "$a"
89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ sh command.sh 10 15
10
11
12
13
14

上面是三个例子分别介绍了单个命令执行结果传递给shell变量
执行py脚本中脚本print的结果赋值给shell变量(py也可以换成可执行jar print的结果)等其他语言。
这个场景可以用于 批量文件 过滤获取指定内容 进行shell处理。

shell 获取输入

#!/usr/bin/env bash
echo "请输入确认与否 y确认 n否认"
read conform
if [ $conform != "y" ]; then
    echo "不执行 结束执行"
    exit 1
fi
echo $conform

执行

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ sh command.sh
请输入确认与否 y确认 n否认
y
y

89264@KX-64006A33CA17 MINGW64 ~/Desktop
$ sh command.sh
请输入确认与否 y确认 n否认
n
不执行 结束执行

ssh在目标主机执行命令

前提
1.目标主机免密
基于公私钥认证 (一般都是这个)
SSH使用expect自动输入密码、命令实现非交互式密码授权
2.主要参数
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]  
           [-D [bind_address:]port] [-e escape_char] [-F configfile]  
           [-I pkcs11] [-i identity_file]  
           [-L [bind_address:]port:host:hostport]  
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]  
           [-R [bind_address:]port:host:hostport] [-S ctl_path]  
           [-W host:port] [-w local_tun[:remote_tun]]  
           [user@]hostname [command]  

-l 指定登入用户
-p 设置端口号
-f 后台运行,并推荐加上 -n 参数
-n 将标准输入重定向到 /dev/null,防止读取标准输入。如果在后台运行ssh的话(-f选项),就需要这个选项。
-N 不执行远程命令,只做端口转发
-q 安静模式,忽略一切对话和错误提示
-T 禁用伪终端配置
-t (tty)为远程系统上的ssh进程分配一个伪tty(终端)。如果没有使用这个选项,当你在远程系统上运行某条命令的时候,ssh不会为该进程分配tty(终端)。相反,ssh将会把远端进程的标准输入和标准输出附加到ssh会话上去,这通常就是你所希望的(但并非总是如此)。这个选项将强制ssh在远端系统上分配tty,这样那些需要tty的程序就能够正常运行。
-v verbose)显示与连接和传送有关的调试信息。如果命令运行不太正常的话,这个选项就会非常有用。
举例

# 执行简单的单个命令 也可以执行目标主机的特定脚本 比如启动tomcat等等
ssh user@remoteNode "cd /home"
# 执行简单的多个拼接命令
ssh user@remoteNode "cd /home;ls"

# 执行shell脚本
# 第一种就是 scp到目标主机特定位置 再用上面的方式执行脚本

# 第二种 未验证  例子如下 
# 远程执行的内容在"< < remotessh " 至" remotessh "之间,在远程机器上的操作就位于其中,注意的点:<< remotessh,ssh后直到遇到remotessh这样的内容结束,remotessh可以随便修改成其他形式。在结束前,加exit退出远程节点 如果不想日志文件在本机出现可以修改配置

#!/bin/bash  
ssh [email protected]   < < remotessh  
ls
cd /data/apache-tomcat-7.0.53/webapps/  
exit  
remotessh 

shell命令拼接

在 shell 中,担任”连续指令”功能的符号就是”分号”。

cd /home;ls

shell中的单引号和双引号

' '    单引号 (single quote)
被单引号用括住的内容,将被视为单一字串。在引号内的代表变数的$符号,没有作用,也就是说,他被视为一般符号处理,防止任何变量替换。
[root@localhost ~]# heyyou=homeecho
[root@localhost ~]# echo '$heyyou'
$heyyou
" "    双引号 (double quote)
被双引号用括住的内容,将被视为单一字串。它防止通配符扩展,但允许变量扩展。这点与单引数的处理方式不同。
[root@VM_16_9_centos ~]# heyyou=homeecho
[root@VM_16_9_centos ~]# echo ${heyyou}
homeecho
[root@VM_16_9_centos ~]# echo '${heyyou}'
${heyyou}
[root@VM_16_9_centos ~]# echo "${heyyou}"
homeecho

其他

$?    状态值 (status variable)
一般来说,Linux 系统的进程以执行系统调用exit()来结束的。这个回传值就是status值。回传给父进程,用来检查子进程的执行状态。
一般指令程序倘若执行成功,其$?回传值为 0;若执行失败,则$?回传值为 1。


$$    当前shell的PID
由于进程的ID是唯一的,所以在同一个时间,不可能有重复性的 PID。有时,script会需要产生临时文件,用来存放必要的资料。而此script亦有可能在同一时间被使用者们使用。在这种情况下,固定文件名在写法上就显的不可靠。唯有产生动态文件名,才能符合需要。符号$$或许可以符合这种需求。它代表当前shell 的 PID。


输出/输入重导向 > 、>>、< 、<< 、<>、>&、>&2
文件描述符(File Descriptor),用一个数字(通常为0-9)来表示一个文件。
常用的文件描述符如下:
文件描述符 名称 常用缩写 默认值
0   标准输入 stdin 键盘
1   标准输出 stdout 屏幕
2   标准错误输出 stderr 屏幕
在简单地用<或>时,相当于使用 0< 或 1>。如下面说明: 
# cmd > file
把cmd命令的输出重定向到文件file中。如果file已经存在,则清空原有文件,使用bash的noclobber选项可以防止复盖原有文件。[即>表示覆盖内容]
# cmd >> file
把cmd命令的输出重定向到文件file中,如果file已经存在,则把信息加在原有文件後面。 [即>>表示追加内容]
# cmd < file
使cmd命令从file读入
# cmd << text
从命令行读取输入,直到一个与text相同的行结束。除非使用引号把输入括起来,此模式将对输入内容进行shell变量替换。如果使用<<- ,则会忽略接下来输入行首的tab,结束行也可以是一堆tab再加上一个与text相同的内容,可以参考後面的例子。
# cmd <<< word
把word(而不是文件word)和後面的换行作为输入提供给cmd。
# cmd <> file
以读写模式把文件file重定向到输入,文件file不会被破坏。仅当应用程序利用了这一特性时,它才是有意义的。
# cmd >| file
功能同>,但即便在设置了noclobber时也会复盖file文件,注意用的是|而非一些书中说的!,目前仅在csh中仍沿用>!实现这一功能。
: > filename 把文件\"filename\"截断为0长度.# 如果文件不存在, 那么就创建一个0长度的文件(与'touch'的效果相同).
# cmd >&n    把输出送到文件描述符n
# cmd m>&n    把输出 到文件符m的信息重定向到文件描述符n
# cmd >&-    关闭标准输出
# cmd <&n   输入来自文件描述符n
# cmd m<&n  m来自文件描述各个n
# cmd <&-    关闭标准输入
# cmd <&n- 移动输入文件描述符n而非复制它。(需要解释)
# cmd >&n- 移动输出文件描述符 n而非复制它。(需要解释)
注意: >&实际上复制了文件描述符,这使得cmd > file 2>&1与cmd 2>&1 >file的效果不一样。
关于EOF用法:https://www.cnblogs.com/kevingrace/p/6257490.html
通常在执行一个命令时,如果不想打印命令执行的结果(包括正确或错误的结果信息),则通常使用"command >/dev/null 2>&1"

sed 工具

最近发现几百台服务器的某个配置文件需要对某个参数实现调整,在拥有ip列表的前提下实现批量调整,就是结合 ssh 与 sed 进行的 比如端口 8090 要改成 9090
这个字符串全文唯一

ssh usr@ip "sed -i 's/8090/9090/g' /usr/local/xxx.yml"

sed推荐阅读
    https://blog.viakiba.cn/2020/07/17/Linux%E5%91%BD%E4%BB%A4%E4%B9%8BSED/
    https://linux.cn/article-11367-1.html

Search

    Table of Contents