Bash-Script 应用案例

系统功能

查询当前系统信息

手动查询:

uname -a

尽管这个方法最为常用,但在脚本中,它有时无法显示诸如 Debian、Ubuntu 这样的信息,而是

Debian >> uname -a
Linux v-dj 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2 (2017-04-30) x86_64 GNU/Linux

Ubuntu >> uname -a
Linux v-ux 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

i5os >> uname -a
Linux i5 3.14.18-ipipe #116 SMP PREEMPT Tue Nov 20 18:27:25 PST 2018 i686 i686 i686 GNU/Linux

Windows >> uname -a
MSYS_NT-6.1 N-SH-465 2.10.0(0.325/5/3) 2018-03-15 14:12 x86_64 Msys

Termux >> uname -a
Linux localhost 3.10.61+ #1 SMP PREEMPT Sat Jul 1 17:40:54 CST 2017 aarch64 Android

方法1: lsb_release -a

lsb_release -i | awk '{print $3}'

方法2:

cat /etc/issue | awk '{print $1}'

方法3: just for centos/fedora

cat /etc/redhat-release

使用 Python 脚本实现功能

def system(str_cmd):
    try:
        status = subprocess.run(str_cmd, shell=True)
    except AttributeError:
        status = subprocess.call(str_cmd, shell=True)
    return status

def system2(str_cmd):
    bytes_stdout = subprocess.check_output(str_cmd, shell=True)
    return bytes_stdout.decode("utf8")  # rstrip("
")


def _D_os_release_version():  # deprecated
    str_shell = [
        # 方法1: lsb_release -a
        "lsb_release -i | awk '{print $3}' ",
        # 方法2: cat /etc/issue
        "cat /etc/issue | awk '{print $1}' ",
        # 方法3: cat /etc/redhat-release  # for centos/fedora
        "cat /etc/redhat-release"  # 未测试??
    ]

    def trying(index):
        try:
            os_version = system2(str_shell[index])
            return os_version if os_version else None
        except Exception as e:
            logging.exception("os_release_version() -->> {}".format(e))
            trying(index + 1)

    trying(0)

def os_release_version():
    try:
        # 方法1: lsb_release -a
        str_shell = "lsb_release -i | awk '{print $3}' "
        os_version = system2(str_shell)
    except subprocess.CalledProcessError:  # 不存在 lsb_release 命令
        logging.debug("os_release_version() -->> 不存在'lsb_release'命令,非Debian系列发行版")

        # 方法2: cat /etc/issue
        if os.path.exists("/etc/issue"):
            str_shell = "cat /etc/issue | awk '{print $1}' "
        # 方法3: cat /etc/redhat-release  # for centos/fedora
        elif os.path.exists("/etc/redhat-release"):
            str_shell = "cat /etc/redhat-release"  # 未测试??
        else:
            # 未查询到当前系统的类型/发行版
            logging.warn("os_release_version() -->> 未知的操作系统发行版")
            system("uname -a")
            return None

        try:
            os_version = system2(str_shell)
        except Exception as e:
            logging.error("os_release_version() -->> {}".format(e))

    os_version = os_version.rstrip("
").lower() if os_version else None
    return os_version
View Code

文件IO操作

逐行读取文件

flag=0
cat data.txt | while read line
do
    if [[ flag -eq 0 ]]; then
        # echo $line
        if [ "$line" == "__ARCHIVE_BELOW__" ]; then
            ((flag=1))
        fi
    else
        echo $line >> temp_1.tar
    fi
done

当前脚本只运行一个实例

LOCK=/var/file.lock
set -o noclobber  # 设置禁止重定向覆盖
if [ -f $LOCK ]; then
    echo "file.sh already running..."
    exit
else
    echo "$$" > $LOCK
    trap 'rm -f "$LOCK"; exit $?' INT TERM EXIT
fi

# do anything here...

网络测试

自动 ping 测试

host_addr="192.168.234.231"
conn_num=0
timeout=3  # 设定等待时间
until [ $conn_num -gt 1 ]; do  # 此处的1可以改写,用来衡量网络稳定系数
    conn_num=$(ping -c 4 -w $timeout $host_addr | grep icmp_seq | wc -l)
    sleep 5.0  # 等待网络调整,或者执行其他动作
done

检测端口是否打开

1. 通过 netcat 工具

2. 利用 wget 测试

3. 利用 telnet 检测

当远程设备的端口未开启时,命令会自动退出:

但当远程设备端口开启时,telnet 会进入连接模式,需要键入 '^]' 指令退出:

在脚本编程中,如何优雅的退出 telnet 命令?

输出结果后立即退出

$ echo "" | telnet 101.199.97.65 8022

Trying 101.199.97.65...
Connected to 101.199.97.65.  #已成功连通端口
Escape character is '^]'.
Connection closed by foreign host.  # 自动退出

输出结果后延迟退出

$ sleep 0.1 | telnet 101.199.97.65 8022

脚本如何判断 telnet 的执行结果?

sleep 0.1 | telnet 10.10.70.138 5900 | grep Connected | wc -l

通过上述命令,如存在Connected关键字,则wc计数为1,否则为0,来判断端口是否连接成功。

另外,实践中发现,telnet不会检测网络连接状态。所以最好在检测端口前,先通过ping指令确认网络能够连接,再测试端口

综上,提供脚本实例:

function try_host_port {
host_addr="192.168.234.231"
port=5900

    local timeout=3  # 设定等待时间
    conn_num=$(ping -c 4 -w $timeout $host_addr | grep icmp_seq | wc -l)
    if [ $conn_num -lt 1 ]; then  # 此处的1可以改写,用来衡量网络稳定系数
        echo "False"
        return 1
    fi

    # 验证VNC端口,并等待端口开启
    local port_status=0
    until [ $port_status -eq 1 ]; do
        port_status=$(sleep 1 | telnet ${host_addr} ${port} | grep Connected | wc -l)
        sleep 1  # 轮询周期
    done
}
 
原文地址:https://www.cnblogs.com/brt3/p/10114275.html