shell基础学习——重要符号功能及用途

目录

$    变量和命令替换

" "    ' '    单引号和双引号

`   反引号

\   反斜杠

;  命令分隔符

&&  ||  !逻辑与、逻辑或、逻辑非

|   管道符

<  输入重定向

>  >>  2> &> 输出重定向

&  后台执行、合并重定向

()  独立子shell、命令替换、算术运算

{}  命令块、子shell

[]   [[]]   条件测试

*    ? 通配符

#   注释

!  历史命令

:  空命令

@  全部


$    变量和命令替换

#变量替换:引用变量的值。
var="Hello"
echo $var  # 输出 Hello

#命令替换:将命令的输出作为值。
result=$(ls)
echo $result  #输出 ls命令的结果

" "    ' '    单引号和双引号

#双引号:保留字符串中的大部分字符,但允许变量替换和命令替换。
var="world"
echo "Hello, $var"  # 输出 Hello, world

#单引号:强引用字符串,保留字符串中的所有字符。
echo 'Hello, $var'  # 输出 Hello, $var

其中,双引号弱引用可以包含变量替换、命令替换和转义字符。

#!/bin/bash

name="Alice"
date=$(date)
message="Welcome, $name. Today's date is $date."

# 输出包含变量和命令替换的消息
echo "$message"

# 包含特殊字符
echo "Special characters: \$ \` \\"

# 包含单引号
echo "It's a great day to learn Shell scripting!"

# 包含空格和制表符
spaced_message="This is a    message with spaces"
echo "$spaced_message"

# 复杂的变量引用
part1="Hello"
part2="world"
echo "$part1, ${part2}!"

其中,单引号强引用的意思是其中的内容会被原样保留,不会被 Shell 解释或扩展。这包括变量替换、命令替换、反斜杠转义等。

#1.强引用字符串
#单引号最主要的用途是强引用字符串中的所有字符,这意味着字符串内的任何字符都不会被 Shell 解释。

echo 'Hello, world!'
# 输出:Hello, world!

#2.保留特殊字符原样
#使用单引号时,字符串内的特殊字符(如 $, \, `, 和 ! 等)不会被解释。

echo 'This is a $dollar sign and a `backtick`'
# 输出:This is a $dollar sign and a `backtick`

#3.避免 Shell 命令注入
#在处理用户输入时,可以使用单引号来防止 Shell 命令注入。
#但是如果输入包含单引号,其本身需要被转义。

# 获取用户输入
read -p "Enter some input: " user_input
echo 'User input: '"$user_input"


`   反引号

#命令替换,与 $() 功能相同,但建议使用 $() 。
result=`ls`
echo $result

\   反斜杠

# 1. 转义特殊字符
# 换行符 \n:表示换行。
echo -e "Line 1\nLine 2"

# 制表符 \t:表示水平制表符(Tab)。
echo -e "Column 1\tColumn 2"

# 回车符 \r:表示回车。
echo -e "Before\rAfter"

# 双引号 \":表示双引号本身。
echo "She said, \"Hello!\""

# 单引号 \':表示单引号本身。
echo 'He said, '\''Hi!'\'




# 2. 防止特殊字符的特殊含义
# 例如特殊字符 $、*、? 等
echo "The price is \$10"



# 3. 文件路径中的转义
# 在文件路径中,有时需要转义特殊字符或空格,以确保Shell能够正确解释文件名。
cd /path/to/some\ directory/
#这里的 \  表示空格。



# 4. 正则表达式中的转义
# 在正则表达式中,某些字符具有特殊含义,使用 \ 可以取消它们的特殊含义。
grep "pattern\." file.txt
#这里的 \. 表示匹配点号 . 而不是任意字符。



# 注意:
# 在双引号 " 内部,\ 能够转义大多数特殊字符
# 但在单引号 ' 内部,\ 只能转义单引号 ' 本身。

;  命令分隔符

#用于分隔多个命令。
echo "First command"; echo "Second command"

&&  ||  !逻辑与、逻辑或、逻辑非

#&&:前一个命令成功时执行后一个命令。
echo "First command" && echo "Second command"

#||:前一个命令失败时执行后一个命令。
echo "First command" || echo "Second command"

|   管道符

  • 管道符 | 是实现Shell脚本中流式处理和数据传递的关键工具。
  • 管道中的每个命令都是独立运行的,每个命令的标准输出会被管道传递给下一个命令的标准输入。
  • 可以通过多个管道符 | 来连接多个命令,形成复杂的管道操作链。
#将一个命令的输出作为下一个命令的输入。
ls | grep "pattern"

<  输入重定向

#将文件内容作为命令的输入。
wc -l < file.txt

>  >>  2> &> 输出重定向

# >将命令输出重定向到文件(覆盖文件)。
echo "Hello" > file.txt

# >>将命令输出追加到文件。
echo "World" >> file.txt

# 标准错误重定向 2> 将命令的错误输出保存到文件中
command 2> error.log

# 合并重定向 &> 将命令的输出和错误输出都保存到文件中
command &> output_and_error.log

&  后台执行、合并重定向

# 将命令放到后台执行。不会阻塞当前Shell的进程,允许同时执行其他命令。
long_running_command &

# 合并重定向 &> 将命令的输出和错误输出都保存到文件中
command &> output_and_error.log

()  独立子shell、命令替换、算术运算

# 如果需要保护和隔离一组命令的操作,通常使用 () 来创建子Shell;
# 如果只是想将一组命令组织成一个整体,使用 {} 就可以了。
# 创建一个子Shell,在子Shell中执行的命令不会影响到外部Shell的环境,包括变量和工作目录等。
# 在需要临时更改环境或执行一系列命令的情况下使用。
# 在子Shell 中执行命令
(
    echo "Inside the subshell"
    cd /tmp
    ls -l
)
# 这里的 cd 和 ls 不会影响外部 Shell 的工作目录和环境

# 在子Shell 中定义变量
(
    MY_VAR="Value in subshell"
    echo "Inside the subshell: MY_VAR=$MY_VAR"
)
# 外部 Shell 中不会有 MY_VAR 变量定义

# 在子Shell 中使用子进程运行命令
(
    echo "This command runs in a subshell" | grep "subshell"
)
# 外部 Shell 不会受到此命令的影响,输出仅在子Shell 内




# 命令替换,将命令的输出作为一个整体插入到命令行中。
# 用于将命令的输出结果赋值给变量、作为另一个命令的参数等。
# 将命令的输出赋值给变量
current_date=$(date +%Y-%m-%d)
echo "Current date is: $current_date"

# 在命令行中使用命令替换
echo "There are $(ls -l | wc -l) files in the current directory"




# 执行算术运算,其中的表达式会被当作算术表达式进行求值。
# 用于执行整数运算、比较和赋值。
# 算术运算
(( x = 5 + 3 ))
echo "Result of arithmetic operation: $x"

# 条件判断
(( y > 10 )) && echo "y is greater than 10"

# 使用变量和算术运算
a=5
b=3
(( c = a * b ))
echo "Result of multiplication: $c"

{}  命令块、子shell

# 命令块:将命令组在当前 Shell 中执行。其内部的命令可以使用分号 ; 或换行符分隔。
{ echo "First command"; echo "Second command"; }

# 在一个命令组中执行多个命令
{
    echo "Command 1"
    echo "Command 2"
    echo "Command 3"
}

# 在命令组中使用变量
var="Hello"
{
    echo "$var, World!"
    echo "This is a command group"
}

# 在 if 语句中使用命令组
if [ "$USER" = "root" ]; then
    {
        echo "Welcome, root user!"
        echo "You have administrative privileges."
    }
fi





# 子shell,在需要临时更改环境或者执行独立于当前Shell的操作时使用。
# 如果需要保护和隔离一组命令的操作,通常使用 () 来创建子Shell;
# 如果只是想将一组命令组织成一个整体,使用 {} 就可以了。
# 在子Shell 中执行命令
{
    echo "Inside the subshell"
    cd /tmp
    ls -l
}
# 这里的 cd 和 ls 不会影响外部 Shell 的工作目录和环境

# 在子Shell 中定义变量
{
    MY_VAR="Value in subshell"
    echo "Inside the subshell: MY_VAR=$MY_VAR"
}
# 外部 Shell 中不会有 MY_VAR 变量定义

# 在子Shell 中使用子进程运行命令
{
    echo "This command runs in a subshell" | grep "subshell"
}
# 外部 Shell 不会受到此命令的影响,输出仅在子Shell 内

[]   [[]]   条件测试

#[]传统的条件测试。方括号内的表达式需要被空格包围。
if [ -f file.txt ]; then
    echo "File exists"
fi

# 字符串比较
if [ "$var1" = "$var2" ]; then
    echo "Variables are equal"
fi

# 数值比较
if [ "$num1" -gt "$num2" ]; then
    echo "$num1 is greater than $num2"
fi

# 文件属性检查
if [ -f "$file" ]; then
    echo "$file exists and is a regular file"
fi



#[[]]是bash的扩展的条件测试,支持更多功能。
#例如逻辑运算符(&&、||)、模式匹配(=、!=)、正则表达式匹配(=~)等。
#不需要对表达式内部的变量使用引号。
#字符串比较
if [[ $var == "value" ]]; then
    echo "Match"
fi

# 数值比较
if [[ "$num1" -gt "$num2" ]]; then
    echo "$num1 is greater than $num2"
fi

# 正则表达式匹配
if [[ "$str" =~ ^[0-9]+$ ]]; then
    echo "$str consists only of digits"
fi

# 逻辑运算
if [[ "$condition1" && "$condition2" ]]; then
    echo "Both conditions are true"
fi

*    ? 通配符

#*用于匹配零个或多个字符。
ls *.txt

# 列出当前目录下的所有文件和文件夹
ls *

# 匹配以 .txt 结尾的所有文件
ls *.txt

# 匹配以 test 开头的所有文件
ls test*





#?用于匹配单个字符。
ls file?.txt

# 列出当前目录下所有有一个字符的文件或文件夹
ls ?

# 匹配以 a 开头,接一个字符,再接 .txt 结尾的文件
ls a?.txt

# 匹配任意三个字符的文件或文件夹
ls ???



# 结合使用*和?
# 匹配以 a 开头,任意多个字符,再接一个字符,最后是 .txt 结尾的文件
ls a*?.txt
#一开始觉得这个没必要,但是a.txt就不符合这个要求,?的作用是要匹配 a 后至少一个字符的文件

# 匹配以 a 开头,中间有一个字符,再接任意多个字符,然后是 .txt 结尾的文件
ls a?*.txt
#和上面一条会产生相同的结果



#与[]一起使用
# 匹配以 file 开头,接一个字符,然后是 .txt 结尾的文件
ls file[0-9].txt

# 匹配以 f 开头,然后是 a 或 b,再接任意字符的文件
ls f[ab]*

# 匹配以 t 开头,然后是 a 到 z 之间的任何一个字符,再接任意字符的文件
ls t[a-z]*

#   注释

#注释单行
# This is a comment
echo "Hello"

!  历史命令

!!  # 执行上一个命令
!n  # 执行第 n 个命令
!-n # 执行倒数第 n 个命令

# 使用 !echo 执行最近的以 echo 开头的命令
!echo

# 使用 !?command? 执行最近的包含 command 的命令
!?command?

# 使用 ^command^cmd 替换上一个命令中的字符串
^command^cmd

# 使用 !$ 引用上一个命令的最后一个参数
echo "Last argument of previous command: !$"

# 使用 !* 引用上一个命令的所有参数
echo "All arguments of previous command: !*"

:  空命令

#!/bin/bash

# 占位符
if [ "$1" == "test" ]; then
    :  # 占位符
else
    echo "Not in test mode"
fi

# 初始化变量
: "${var:=default_value}"
echo "$var"

# 保持循环结构完整
count=0
while [ $count -lt 3 ]; do
    echo "Count: $count"
    :  # 占位符
    ((count++))
done

# 防止未定义变量错误
: "${UNDEFINED_VAR:?Variable not set or empty}"

# 重定向使用
: > empty_file.txt
echo "File 'empty_file.txt' has been cleared."

# 调试和开发
echo "This is before the empty command."
:  # echo "This command is temporarily disabled."
echo "This is after the empty command."

@  全部

#!/bin/bash

# 定义数组
fruits=("apple" "banana" "cherry")

# 引用数组的所有元素
echo "All fruits: ${fruits[@]}"
#输出All fruits: apple banana cherry

# 遍历数组元素
for fruit in "${fruits[@]}"; do
    echo "Fruit: $fruit"
done
#输出:
#Fruit: apple
#Fruit: banana
#Fruit: cherry

# 获取数组长度
length=${#fruits[@]}
echo "Number of fruits: $length"
#输出Number of fruits: 3

# 批量替换
echo "Fruits with 'a' replaced by 'A': ${fruits[@]/a/A}"
#输出Fruits with 'a' replaced by 'A': Apple bAnAnA cherry

# 引用所有脚本参数
echo "All script parameters: $@"
#输出All script parameters: one two three

# 引用所有脚本参数并保留引号
echo "All script parameters with quotes preserved:"
for arg in "$@"; do
    echo "$arg"
done
#输出
#All script parameters with quotes preserved:
#one two
#three

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值