shell常用语法总结【常用的判断、变量定义及有用的str操作、重定向符使用】

1、判断文件or文件夹

    if [ ! -d "${CUR_FOLDER}/logs" ]; then
        # 创建日志目录
        mkdir -p ${CUR_FOLDER}/logs
        if [ $? -ne 0 ]; then
            log_warn "日志目录【${CUR_FOLDER}/logs】创建失败" # log_warn是定义的另一个方法
            exit 0
        fi
    fi

代码含义

这个代码片段是一个Shell脚本,用于检查并创建日志目录。具体步骤如下:

  1. 检查${CUR_FOLDER}/logs目录是否存在。
  2. 如果目录不存在,则创建该目录。
  3. 检查目录创建是否成功。
  4. 如果创建失败,输出警告信息并退出脚本。

if 的用法

if 是条件判断语句,用于根据条件的真假来执行不同的代码块。在Shell脚本中,if 语句的基本结构如下:

if [ 条件 ]; then
    # 条件为真时执行的代码
else
    # 条件为假时执行的代码
fi

! 的含义

! 是逻辑非运算符,用于取反。也就是说,如果条件为真,! 会将其变为假;如果条件为假,! 会将其变为真。在这个代码中,[ ! -d "${CUR_FOLDER}/logs" ] 的意思是“如果 ${CUR_FOLDER}/logs 目录不存在”。

$? 的含义

$? 是一个特殊变量,用于获取上一个命令的退出状态码。通常,命令成功执行返回0,失败返回非0值。在这个代码中,if [ $? -ne 0 ]; then 用于检查上一个命令(即 mkdir -p ${CUR_FOLDER}/logs)是否成功执行。

d 的含义

  • d 是一个文件测试选项,用于检查指定路径是否为目录。在这个代码中,[ -d "${CUR_FOLDER}/logs" ] 用于检查 ${CUR_FOLDER}/logs 是否存在且为目录。

ne 的含义

  • ne 是数值比较运算符,表示“不等于”。在这个代码中,[ $? -ne 0 ] 的意思是“如果上一个命令的退出状态码不等于0”。

其他常见的文件测试选项

  • e:检查文件是否存在。
  • f:检查是否为普通文件。
  • r:检查文件是否可读。
  • w:检查文件是否可写。
  • x:检查文件是否可执行。

希望这些解释对你有帮助!如果有其他问题,请随时提问。

2、数值判断

在 Shell 脚本中,常见的数值比较运算符包括:

  • eq:等于 (equal)
  • ne:不等于 (not equal)
  • lt:小于 (less than)
  • le:小于或等于 (less than or equal)
  • gt:大于 (greater than)
  • ge:大于或等于 (greater than or equal)

示例

a=5
b=10

if [ $a -eq $b ]; then
    echo "a 等于 b"
fi

if [ $a -ne $b ]; then
    echo "a 不等于 b"
fi

if [ $a -lt $b ]; then
    echo "a 小于 b"
fi

if [ $a -le $b ]; then
    echo "a 小于或等于 b"
fi

if [ $a -gt $b ]; then
    echo "a 大于 b"
fi

if [ $a -ge $b ]; then
    echo "a 大于或等于 b"
fi

解释

  • eq:检查 a 是否等于 b
  • ne:检查 a 是否不等于 b
  • lt:检查 a 是否小于 b
  • le:检查 a 是否小于或等于 b
  • gt:检查 a 是否大于 b
  • ge:检查 a 是否大于或等于 b

这些运算符可以帮助你在 Shell 脚本中进行数值比较,从而实现不同的逻辑判断。

3、变量的参数扩展

参数扩展(Parameter Expansion)是 Shell 脚本中非常强大的功能,可以用来操作变量的值。

基本语法

${parameter}

这是最基本的参数扩展,用于获取变量的值。

删除前缀和后缀

  1. 删除最短匹配的前缀

    ${variable#pattern}
    

    示例:

    file="path/to/myfile.txt"
    echo ${file#*/}  # 输出: to/myfile.txt
    
  2. 删除最长匹配的前缀

    ${variable##pattern}
    

    示例:

    file="path/to/myfile.txt"
    echo ${file##*/}  # 输出: myfile.txt
    
  3. 删除最短匹配的后缀

    ${variable%pattern}
    

    示例:

    file="path/to/myfile.txt"
    echo ${file%.*}  # 输出: path/to/myfile
    
  4. 删除最长匹配的后缀

    ${variable%%pattern}
    

    示例:

    file="path/to/myfile.txt"
    echo ${file%%/*}  # 输出: path
    

默认值和替换

  1. 如果变量未定义,则使用默认值

    ${variable:-default}
    

    示例:

    echo ${name:-"default_name"}  # 如果 name 未定义,则输出 "default_name"
    
  2. 如果变量为空或未定义,则使用默认值

    ${variable:=default}
    

    示例:

    name=""
    echo ${name:="default_name"}  # 如果 name 为空,则输出 "default_name"
    
  3. 如果变量未定义,则显示错误信息并退出

    ${variable:?error_message}
    

    示例:

    echo ${name:?"name is not set"}  # 如果 name 未定义,则显示错误信息并退出
    
  4. 如果变量已定义且不为空,则使用替换值

    ${variable:+replacement}
    

    示例:

    name="John"
    echo ${name:+"Hello, $name"}  # 如果 name 已定义且不为空,则输出 "Hello, John"
    

字符串操作

  1. 获取字符串长度

    ${#variable}
    

    示例:

    name="John"
    echo ${#name}  # 输出: 4
    
  2. 子字符串提取

    ${variable:offset:length}
    

    示例:

    name="JohnDoe"
    echo ${name:0:4}  # 输出: John
    
  3. 字符串替换

    ${variable/pattern/replacement}
    

    示例:

    text="Hello World"
    echo ${text/World/Shell}  # 输出: Hello Shell
    
  4. 全局字符串替换

    ${variable//pattern/replacement}
    

    示例:

    text="Hello World World"
    echo ${text//World/Shell}  # 输出: Hello Shell Shell
    

示例

#!/bin/bash

# 定义变量
file_path="/home/user/docs/file.txt"

# 删除最短匹配的前缀
echo ${file_path#*/}  # 输出: home/user/docs/file.txt

# 删除最长匹配的前缀
echo ${file_path##*/}  # 输出: file.txt

# 删除最短匹配的后缀
echo ${file_path%/*}  # 输出: /home/user/docs

# 删除最长匹配的后缀
echo ${file_path%%/*}  # 输出: (空字符串)

# 使用默认值
unset name
echo ${name:-"default_name"}  # 输出: default_name

# 获取字符串长度
name="John"
echo ${#name}  # 输出: 4

# 子字符串提取
echo ${name:1:2}  # 输出: oh

# 字符串替换
text="Hello World"
echo ${text/World/Shell}  # 输出: Hello Shell

# 全局字符串替换
text="Hello World World"
echo ${text//World/Shell}  # 输出: Hello Shell Shell

这些是参数扩展的一些常见用法,可以帮助你在 Shell 脚本中更灵活地操作变量。

4、> >>>>>

#!/bin/bash

#<:文件输入重定向。
#<<:Here Document,多行输入。
#<<<:Here String,单行字符串输入。

cat>a.txt<<EOF
a
bc
def
EOF

# 示例文件内容
echo -e "file_line1\nfile_line2\nfile_line3" > example.txt

# 使用 < 文件输入重定向
echo "使用 < 文件输入重定向:"
cat < example.txt

# 使用 << Here Document
echo -e "\n使用 << Here Document:"
cat << EOF
doc_line1
doc_line2
doc_line3
EOF

# 使用 <<< Here String
echo -e "\n使用 <<< Here String:"
cat <<< "This is a single line string"

5、一些脚本解读


# cluster.conf示例:
#zk_node_1_host=10.87.102.206
#zk_node_1_port=16871
#zk_node_2_host=10.87.102.207
#zk_node_2_port=16871

. ${CUR_FOLDER}/cluster.conf # 等效于 source ${CUR_FOLDER}/cluster.conf把conf读近配置
. ${CUR_FOLDER}/gen_login_cmd.sh # 执行这个shell、加载一些变量和方法

zk_index=1
while true; do
    host_var="zk_node_${zk_index}_host" # host_var

    # 检查所有变量是否为空,若有一个为空则跳出循环
    if [ -z "${
     
     !host_var}" ]; then
        break
    fi
    # 远程安装jdk、zookeeper
    echo $(get_scp_command ${
     
     !host_var} "${DEP_FOLDER}/jdk-8u202-nonroot.tar.gz ${DEP_FOLDER}/apache-zookeeper-3.7.2-bin.tar.gz")
    zk_index=$((zk_index + 1))  # 双层是$(())执行一个运算操作     单层是$()执行一个子shell
done
#!/bin/bash
# install.conf示例:
#ssh.10.87.102.206=root:idss:/opt/idss/ck_cluste
#ssh.10.87.102.207=admin:adminpass:/opt/idss/ck_cluste

# 读取配置文件并解析
CONFIG_FILE="install.conf"
declare -A HOSTS  # 声明一个关联数组【哈希表、字典】
#-a:声明一个索引数组。
#-A:声明一个关联数组(哈希表)。
#-i:声明一个整数变量。
#-r:声明一个只读变量(只读变量不能被修改)。
#-x:声明一个环境变量(将变量导出到子进程)。
#-l:将变量的值转换为小写。
#-u:将变量的值转换为大写。
#-p:显示变量的属性和值。

while IFS='=' read -r key user_password || [[ -n "$key" ]]; do
    key=$(echo "$key" | xargs) # xargs去除前后空格
    user_password=$(echo "$user_password" | xargs)
    if [[ $key == ssh.* ]]; then
        host=${key#ssh.}
        HOSTS["$host"]="$user_password"
    fi
done < "$CONFIG_FILE"  # < 将$CONFIG_FILE中的内容逐行读取并作为while循环的输入。
#<:文件输入重定向。
#<<:Here Document,多行输入。
#<<<:Here String,单行字符串输入。

# 获取 SSH 命令
get_ssh_command() {
    
    
    local host=$1
    local cmd=$2
    local user_password=${HOSTS["$host"]}
    IFS=':' read -r user password install_path<<< "$user_password"
    # read -r key user_password:
# read命令用于从标准输入读取一行,并将其分割成多个变量。
# -r选项告诉read命令不要对反斜杠进行转义。
# user和password、install_path是3个变量,read命令会将等号前的部分赋值给key,等号后的部分赋值给user_password。
    echo "sshpass -p '$password' ssh $user@$host $cmd"
}

# 获取 SCP 命令
get_scp_command() {
    
    
    local host=$1
    local files=$2
    local user_password=${HOSTS[$host]}
    
    # root:idss:/opt/idss/ck_cluste
    IFS=':' read -r user password install_path<<< "$user_password"
    mkdir_cmd=$(get_ssh_command $host "mkdir -p $install_path")
    `$mkdir_cmd`
    echo "sshpass -p '$password' scp -r $files $user@$host:$install_path"
}

# ssh_command=$(get_scp_command "10.87.102.206" "/Users/admin/scripts/dbaudit/ckcluster/dep/jdk-8u202-nonroot.tar.gz /Users/admin/scripts/dbaudit/ckcluster/dep/apache-zookeeper-3.7.2-bin.tar.gz")
# echo $ssh_command
# scp_command=$(get_ssh_command "10.87.102.206" "ls /opt/idss/ck_cluste")
# echo $scp_command
# `$scp_command`

猜你喜欢

转载自blog.csdn.net/qq_42873554/article/details/143366007