Bash 学习摘录2

简介: Bash 学习摘录

Bash 学习摘录1:https://developer.aliyun.com/article/1598574

$OLDPWD

之前的工作目录(“OLD-print-working-directory”, 就是之前你所在的目录)


$OSTYPE

操作系统类型


$PATH

可执行文件的搜索路径, 一般为 /usr/bin/, /usr/X11R6/bin/, /usr/local/bin, 等等。


$PIPESTATUS

这个数组变量将保存最后一个运行的前台管道的退出状态码。 相当有趣的是, 这个退出状态码和最后一个命令运行的退出状态码并不一定相同。


$PPID

进程的 $PPID 就是这个进程的父进程的进程 ID(pid)。


$PROMPT_COMMAND

这个变量保存了在主提示符 $PS1 显示之前需要执行的命令。


$PS1

这是主提示符, 可以在命令行中见到它。


$PS2

第二提示符, 当你需要额外输入的时候, 你就会看到它。 默认显示 “>” 。


$PS3

第三提示符, 它在一个 select 循环中显示 。


$PS4

第四提示符, 当你使用 -x 选项来调用脚本时, 这个提示符会出现在每行输出的开头。 默认显示 “+” 。


$PWD

工作目录(你当前所在的目录)


$REPLY

当没有参数变量提供给 read 命令的时候, 这个变量会作为默认变量提供给 read 命令。 也可以用于 select 菜单, 但是只提供所选择变量的编号, 而不是变量本身的值。


$SECONDS

这个脚本已经运行的时间(以秒为单位)。


$SHELLOPTS

shell 中已经激活的选项的列表, 这是一个只读变量。

bash$ echo $SHELLOPTS
braceexpand:hashall:histexpand:monitor:history:interactivecomments:emacs

$SHLVL

Shell 级别, 就是 Bash 被嵌套的深度。 如果是在命令行中, 那么 $SHLVL 为 1, 如果在脚本中那么 $SHLVL 为 2 。


$TMOUT

如果 $TMOUT 环境变量被设置为非零值 time 的话, 那么经过 time 秒后, shell 提示符将会超时。 这将会导致登出(logout)。


$UID

用户 ID 号。当前用户的用户标识号, 记录在 /etc/passwd 文件中

位置参数

  • $0, $1, $2, 等等。
    位置参数, 从命令行传递到脚本, 或者传递给函数, 或者 set 给变量
  • $#
    命令行参数或者位置参数的个数
  • $*
    所有的位置参数都被看作为一个单词。
  • “$*” 必须被引用起来。
  • $@
    与 $* 相同, 但是每个参数都是一个独立的引用字符串, 这就意味着, 参数是被完整传递的, 并没有被解释或扩展。 这也意味着, 参数列表中每个参数都被看作为单独的单词。
    “$@” 应该被引用起来。

其他的特殊参数

  • $-
    传递给脚本的标记(使用 set 命令)。
  • $!
    运行在后台的最后一个作业的 PID(进程 ID
  • $_
    这个变量保存之前执行的命令的最后一个参数的值
  • $?
    命令, 函数, 或者是脚本本身的退出状态码
  • $$
    脚本自身的进程 ID$$ 变量在脚本中经常用来构造 “唯一的” 临时文件名

(2) 操作字符串

    Bash 所支持的字符串操作的数量多的令人惊讶。 但是不幸的是, 这些工具缺乏统一的标准。 一些是参数替换的子集, 而另外一些则受到 UNIX expr 命令的影响。 这就导致了命令语法的不一致, 还会引起冗余的功能, 但是这些并没有引起混乱。

expr --help
用法:expr 表达式
 或:expr 选项

      --help        显示此帮助信息并退出
      --version     显示版本信息并退出

将 <表达式> 的值打印到标准输出。以下运算符按优先级从低到高排列,不同
优先级之间以空行隔开。<表达式> 可以是:

  参数1 | 参数2     若 <参数1> 的值不为 0 或 null,则返回 <参数1>,
                      否则返回 <参数2>

  参数1 & 参数2     若两边的值都不为 0 或 null,则返回 <参数1>,否则返回 0

  参数1 < 参数2     <参数1> 小于 <参数2>
  参数1 <= 参数2    <参数1> 小于或等于 <参数2>
  参数1 = 参数2     <参数1> 等于 <参数2>
  参数1 != 参数2    <参数1> 不等于 <参数2>
  参数1 >= 参数2    <参数1> 大于或等于 <参数2>
  参数1 > 参数2     <参数1> 大于 <参数2>

  参数1 + 参数2     计算 <参数1> 加 <参数2> 的和
  参数1 - 参数2     计算 <参数1> 减 <参数2> 的差

  参数1 * 参数2     计算 <参数1> 乘以 <参数2> 的积
  参数1 / 参数2     计算 <参数1> 除以 <参数2> 的商
  参数1 % 参数2     计算 <参数1> 除以 <参数2> 的余数

  字符串 : 正则     在 <字符串> 起始处进行 <正则> 的模式匹配

  match 字符串 正则          等于 "字符串 : 正则"
  substr 字符串 位置 长度    求 <字符串> 的子串,<位置> 从 1 开始数
  index 字符串 字符          在 <字符串> 中搜索 <字符> 中任何一个,返回其索引,
                               如未找到则返回 0
  length 字符串              <字符串> 的长度
  + 记号                     将 <记号> 解释为字符串,即使它是一个关键字,
                               例如 "match",或者运算符,例如 "/"

  ( 表达式 )                 <表达式> 的值

请注意,由于 shell 这一层的存在,可能有许多运算符需要转义或者加引号。
如果两个 <参数> 都是数字,比较运算符就是算术比较,否则就是字典序比较。
模式匹配会返回 \( 和 \) 之间的字符串匹配的字符串,若没有匹配则返回 null;
如果未使用 \( 和 \),则会返回匹配的字符的个数,若没有匹配则返回 0。

若 <表达式> 的值既不是 null 也不是 0,则退出状态为 0;若 <表达式> 的值为 null
或者 0,则退出状态为 1;如果 <表达式> 的句法无效,则退出状态为 2;如果有错误
发生,则退出状态为 3。

GNU coreutils 在线帮助:<https://www.gnu.org/software/coreutils/>
请向 <http://translationproject.org/team/zh_CN.html> 报告任何翻译错误
完整文档 <https://www.gnu.org/software/coreutils/expr>
或者在本地使用:info '(coreutils) expr invocation'

字符串长度

语法:

${#string}
expr length $string
expr "$string" : '.*'

示例:

stringZ=abcABC123ABCabc

echo ${#stringZ}               # 15
echo $(expr length $stringZ)   # 15
echo $(expr "$stringZ" : '.*') # 15

${#var}

字符串长度 (变量$var得字符个数) 。 对于 array 来说, ${#array} 表示的是数组中第一个元素的长度。

例外情况:

  • ${#*} 和 ${#@} 表示位置参数的个数。
  • 对于数组来说, ${#array[*]} 和 ${#array[@]} 表示数组中元素的个数。

匹配字符串开头的子串长度

语法:

expr match "$string" '$substring'
# $substring 是一个正则表达式.
expr "$string" : '$substring'
# $substring是一个正则表达式.

示例:

stringZ=abcABC123ABCabc
#       |------|

echo $(expr match "$stringZ" 'abc[A-Z]*.2') # 8
echo $(expr "$stringZ" : 'abc[A-Z]*.2')     # 8

索引

语法:

expr index $string $substring
# 在字符串 $string 中所匹配到的 $substring 第一次所出现的位置

示例:

stringZ=abcABC123ABCabc

echo $(expr index "$stringZ" C12)   # 6 
                                    # C 字符的位置
echo $(expr index "$stringZ" 1c)    # 3
# 'c' (in #3 position) matches before '1'.

提取子串

语法:

${string:position}
# 在 $string 中从位置 $position 开始提取子串.
# 如果 $string 是 "*" 或者 "@" , 那么将会提取从位置 $position 开始的位置参数.

${string:position:length}
# 在 $string 中从位置 $position 开始提取 $length 长度的子串.

示例:

stringZ=abcABC123ABCabc
#       0123456789.....
#       0-based indexing.

echo ${stringZ:0}   # abcABC123ABCabc
echo ${stringZ:1}   # bcABC123ABCabc
echo ${stringZ:7}   # 23ABCabc
echo ${stringZ:7:3} # 23A
                    # 提取子串长度为3.

# 能不能从字符串的右边(也就是结尾)部分开始提取子串?
echo ${stringZ:-4} # abcABC123ABCabc
# 默认是提取整个字符串, 就象${parameter:-default}一样. 
# 然而 . . . 

echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4}  # Cabc
# 这样, 它就可以工作了. 
# 使用圆括号或者添加一个空格可以"转义"这个位置参数.

    如果 $string 参数是 "*""@" , 那么将会从 $position 位置开始提取 $length 个位置参数, 但是由于可能没有 $length 个位置参数了,那么就有几个位置参数就提取几个位置参数。

echo ${*:2} # 打印出第2个和后边所有的位置参数.
echo ${@:2} # 同上.

echo ${*:2:3} # 从第2个开始, 连续打印3个位置参数.

#./t.sh 1 2 3 4 5 6
#2 3 4 5 6
#2 3 4 5 6
#2 3 4

语法:

expr substr $string $position $length
# 在 $string 中从 $position 开始提取 $length 长度的子串.

expr match "$string" '\($substring\)'
# 从 $string 的开始位置提取 $substring, $substring 是正则表达式.


expr "$string" : '\($substring\)'
# 从 $string 的开始位置提取 $substring , $substring 是正则表达式.


示例:

stringZ=abcABC123ABCabc
# =======
echo $(expr match "$stringZ" '\(.[b-c]*[A-Z]..[0-9]\)') # abcABC1
echo $(expr "$stringZ" : '\(.[b-c]*[A-Z]..[0-9]\)')     # abcABC1
echo $(expr "$stringZ" : '\(.......\)')                 # abcABC1
# 上边的每个echo都打印出相同的结果.

语法:

expr match "$string" '.*\($substring\)'
# 从 $string 的结尾提取$substring, $substring 是正则表达式.
expr "$string" : '.*\($substring\)'
# 从 $string 的结尾提取 $substring, $substring 是正则表达式.

示例:

stringZ=abcABC123ABCabc
# ======

echo $(expr match "$stringZ" '.*\([A-C][A-C][A-C][a-c]*\)') # ABCabc
echo $(expr "$stringZ" : '.*\(......\)')                    # ABCabc

子串削除

语法:

${string#substring}
# 从 $string 的开头位置截掉最短匹配的 $substring .
${string##substring}
# 从 $string 的开头位置截掉最长匹配的 $substring .

示例:

stringZ=abcABC123ABCabc 
#       |----|
#       |----------|

echo ${stringZ#a*C} # 123ABCabc
# 截掉'a'到'C'之间最短的匹配字符串.

echo ${stringZ##a*C} # abc
# 截掉'a'到'C'之间最长的匹配字符串.

语法:

${string%substring}
# 从 $string 的结尾位置截掉最短匹配的 $substring .
${string%%substring}
# 从 $string 的结尾位置截掉最长匹配的 $substring.

示例:

stringZ=abcABC123ABCabc
#                     ||
#         |------------|

echo ${stringZ%b*c} # abcABC123ABCa
# 从$stringZ的结尾位置截掉'b'到'c'之间最短的匹配. 

echo ${stringZ%%b*c} # a
# 从$stringZ的结尾位置截掉'b'到'c'之间最长的匹配.

子串替换

语法:

${string/substring/replacement}
# 使用 $replacement 来替换第一个匹配的 $substring .

${string//substring/replacement}
# 使用 $replacement 来替换所有匹配的 $substring .

示例:

stringZ=abcABC123ABCabc
echo ${stringZ/abc/xyz}     # xyzABC123ABCabc
                            # 使用'xyz'来替换第一个匹配的'abc'.

echo ${stringZ//abc/xyz}    # xyzABC123ABCxyz
                            # 用'xyz'来替换所有匹配的'abc'.

语法:

${string/#substring/replacement}
# 如果 $substring 匹配 $string 的开头部分, 那么就用 $replacement 来替换 $substring .

${string/%substring/replacement}
# 如果 $substring 匹配 $string 的结尾部分, 那么就用 $replacement 来替换 $substring.

示例:

stringZ=abcABC123ABCabc

echo ${stringZ/#abc/XYZ}    # XYZABC123ABCabc
                            # 用'XYZ'替换开头的'abc'.

echo ${stringZ/%abc/XYZ}    # abcABC123ABCXYZ
                            # 用'XYZ'替换结尾的'abc'.


(3) 参数替换

处理和(或)扩展变量

  • ${parameter}
        与 $parameter 相同, 也就是变量 parameter 的值。
  • ${parameter-default}, ${parameter:-default}

   ${parameter-default} – 如果变量 parameter 没被声明, 那么就使用默认值。

   ${parameter:-default} – 如果变量 parameter 没被设置, 那么就使用默认值。


${parameter=default}, ${parameter:=default}

   ${parameter=default} – 如果变量 parameter 没声明, 那么就把它的值设为 default。

   ${parameter:=default} – 如果变量 parameter 没设置, 那么就把它的值设为 default。

   这两种形式基本上是一样的。 只有在变量 $parameter 被声明并且被设置为 null 值的时候, 才会引起这两种形式的不同。


${parameter+alt_value}, ${parameter:+alt_value}

   ${parameter+alt_value} – 如果变量 parameter 被声明了, 那么就使用 alt_value , 否则就使用 null 字符串。

   ${parameter:+alt_value} – 如果变量 parameter 被设置了, 那么就使用 alt_value , 否则就使用 null 字符串。

   这两种形式绝大多数情况下都一样。 只有在 parameter 被声明并且设置为 null 值的时候, 多出来的这个: 才会引起这两种形式的不同。


${parameter?err_msg}, ${parameter:?err_msg}

   ${parameter?err_msg} – 如果 parameter 已经被声明, 那么就使用设置的值, 否则打印 err_msg 错误消息。

   ${parameter:?err_msg} – 如果 parameter 已经被设置, 那么就使用设置的值, 否则打印 err_msg 错误消息。

   这两种形式绝大多数情况都是一样的。 和上边所讲的情况一样, 只有在 parameter 被声明并设置为 null 值的时候, 多出来的:才会引起这两种形式的不同。

(4)指定变量的类型: 使用 declare 或者 typeset

    declare 或者 typeset 内建命令(这两个命令是完全一样的)允许指定变量的具体类型。 在某些编程语言中, 这是指定变量类型的一种很弱的形式。  declare 命令是从 Bash 2.0 之后才被引入的命令。 typeset 也可以用在 ksh 的脚本中。

declare/typeset 选项

  • -r 只读
declare -r var1

(declare -r var1 与 readonly var1 是完全一样的)

    这和 C 语言中的 const 关键字一样, 都用来指定变量为只读。 如果你尝试修改一个只读变量的值,那么会产生错误信息。

  • -i 整型
declare -i number
# 脚本将会把变量"number"按照整型进行处理。

number=3
echo "Number = $number" # Number = 3

number=three
echo "Number = $number" # Number = 0
# 脚本尝试把字符串"three"作为整数来求值(译者注: 当然会失败, 所以出现值为0)。

    如果把一个变量指定为整型的话, 那么即使没有 expr 或者 let 命令, 也允许使用特定的算术运算。

n=6/3
echo "n = $n" # n = 6/3

declare -i n
n=6/3
echo "n = $n" # n = 2
  • -a 数组
declare -a indices

  变量 indices 将被视为数组。

  • -f 函数
declare -f

    如果在脚本中使用declare -f, 而不加任何参数的话, 那么将会列出这个脚本之前定义的所有函数。

declare -f function_name

  如果在脚本中使用declare -f function_name这种形式的话, 将只会列出这个函数的名字。

  • -x export
declare -x var3

  这句将会声明一个变量, 并作为这个脚本的环境变量被导出。

  • -x var=$value
declare -x var3=373

    declare 命令允许在声明变量类型的同时给变量赋值。

示例:

#!/bin/bash

func1() {
    echo This is a function.
}

declare -f # 列出前面定义的所有函数。
echo

declare -i var1 # var1是个整型变量。
var1=2367
echo "var1 declared as $var1"
var1=var1+1 # 整型变量的声明并不需要使用'let'命令。
echo "var1 incremented by 1 is $var1."
# 尝试修改一个已经声明为整型变量的值。
echo "Attempting to change var1 to floating point value, 2367.1."
var1=2367.1 # 产生错误信息, 并且变量并没有被修改。
echo "var1 is still $var1"

echo

declare -r var2=13.36   # 'declare'允许设置变量的属性,
                        #+ 同时给变量赋值。
echo "var2 declared as $var2" # 试图修改只读变量的值。
var2=13.37                    # 产生错误消息, 并且从脚本退出。

echo "var2 is still $var2" # 将不会执行到这行。

exit 0 # 脚本也不会从此处退出。

(5)变量的间接引用

    假设一个变量的值是第二个变量的名字。 那么我们如何从第一个变量中取得第二个变量的值呢? 比如,如果 a=letter_of_alphabet 并且 letter_of_alphabet=z ,那么我们能够通过引用变量 a 来获得 z 么? 这确实是可以做到的, 它被称为间接引用。 它使用 eval var1=\$$a 这种不平常的形式。

#!/bin/bash

# ind-ref.sh: 间接变量引用. 
# 访问一个以另一个变量内容作为名字的变量的值.(译者注: 怎么译都不顺)

a=letter_of_alphabet # 变量"a"的值是另一个变量的名字.
letter_of_alphabet=z

echo

# 直接引用.
echo "a = $a" # a = letter_of_alphabet

# 间接引用.
eval a=\$$a
echo "Now a = $a" # 现在 a = z

echo

# 现在, 让我们试试修改第二个引用的值.

t=table_cell_3
table_cell_3=24
echo "\"table_cell_3\" = $table_cell_3" # "table_cell_3" = 24
echo -n "dereferenced \"t\" = "
eval echo \$$t # 解引用 "t" = 24
# 在这个简单的例子中, 下面的表达式也能正常工作么(为什么?).
# eval t=\$$t; echo "\"t\" = $t"

echo

t=table_cell_3
NEW_VAL=387
table_cell_3=$NEW_VAL
echo "Changing value of \"table_cell_3\" to $NEW_VAL."
echo "\"table_cell_3\" now $table_cell_3"
echo -n "dereferenced \"t\" now "
eval echo \$$t
# "eval" 带有两个参数 "echo" 和 "\$$t" (与$table_cell_3等价)

echo

# (感谢, Stephane Chazelas, 澄清了上边语句的行为.)

# 另一个方法是使用${!t}符号, 见"Bash, 版本2"小节的讨论. 45 # 也请参考 ex78.sh.

exit 0

    变量的间接引用到底有什么应用价值? 它给 Bash 添加了一种类似于 C 语言指针的功能, 比如, 在表格查找中的用法。

(6)$RANDOM: 产生随机整数

    $RANDOM 是 Bash 的内部函数 (并不是常量), 这个函数将返回一个伪随机整数, 范围在 0 - 32767 之间。 它不应该被用来产生密匙。

#!/bin/bash
# 每次调用$RANDOM都会返回不同的随机整数. 
# 一般范围为: 0 - 32767 (有符号的 16-bit整数).

MAXCOUNT=10
count=1

echo
echo "$MAXCOUNT random numbers:"
echo "-----------------"

while [ "$count" -le $MAXCOUNT ] # 产生10 ($MAXCOUNT)个随机整数. 
do
    number=$RANDOM
    echo $number
    let "count += 1" # 增加计数. 
done
echo "-----------------"

# 如果你需要在特定范围内产生随机整数, 那么使用'modulo'(模)操作.(译者注: 事实上, 这不是一个非常 好的办法. 理由见man 3 rand)
# 取模操作会返回除法的余数. 
RANGE=500

echo

number=$RANDOM
let "number %= $RANGE"
#           ^^
echo "Random number less than $RANGE --- $number"

echo


# 如果你需要产生一个大于某个下限的随机整数. 
#+ 那么建立一个test循环来丢弃所有小于此下限值的整数. 

FLOOR=200

number=0 #初始化
while [ "$number" -le $FLOOR ]
do
    number=$RANDOM
done
echo "Random number greater than $FLOOR --- $number"
echo

# 让我们对上边的循环尝试一个小改动, 如下: 
# let "number = $RANDOM + $FLOOR"
# 这将不再需要那个while循环, 并且能够运行的更快. 
# 但是, 这可能会产生一个问题, 思考一下是什么问题?
# 结合上边两个例子, 来在指定的上下限之间来产生随机数. 
number=0 #initialize
while [ "$number" -le $FLOOR ]
do
    number=$RANDOM
    let "number %= $RANGE" # 让$number依比例落在$RANGE的范围内. 
done
echo "Random number between $FLOOR and $RANGE --- $number"
echo

# 产生二元值, 就是, "true" 或 "false" 两个值. 
BINARY=2
T=1
number=$RANDOM
let "number %= $BINARY"
# 注意 let "number >>= 14" 将会给出一个更好的随机分配. #(译者注: 正如man页中提到的, 更 高位的随机分布更加平均)
#+ (右移14位将把所有的位全部清空, 除了第15位, 因为有符号, 第16位是符号位). #取模操作使用低位来 产生随机数会相对不平均)
if [ "$number" -eq $T ]
then
    echo "TRUE"
else
    echo "FALSE"
fi 

echo

# 抛骰子. 
SPOTS=6 # 模 6 给出的范围是 0 - 5.
# 加 1 会得到期望的范围
# 感谢, Paulo Marcel Coelho Aragao, 对此进行的简化. 
die1=0
die2=0
# 是否让SPOTS=7会比加1更好呢? 解释行或者不行的原因?
# 每次抛骰子, 都会给出均等的机会. 
let "die1 = $RANDOM % $SPOTS +1" # 抛第一次. 
let "die2 = $RANDOM % $SPOTS +1" # 抛第二次. 
# 上边的算术操作中, 哪个具有更高的优先级呢 -- 
#+ 模(%) 还是加法操作(+)?
let "throw = $die1 + $die2"
echo "Throw of the dice = $throw"
echo
exit

(7)双圆括号结构

    与 let 命令很相似, ((…)) 结构允许算术扩展和赋值。 举个简单的例子, a=$(( 5 + 3 )), 将把变量 “a” 设为 “5 + 3” , 或者 8 。然而, 双圆括号结构也被认为是在 Bash 中使用 C 语言风格变量操作的一种处理机制。

#!/bin/bash
# 使用((...))结构操作一个变量, C语言风格的变量操作.

echo

((a = 23)) # C语言风格的变量赋值, "="两边允许有空格.
echo "a (initial value) = $a"

((a++)) # C语言风格的后置自加.
echo "a (after a++) = $a"

((a--)) # C语言风格的后置自减.
echo "a (after a--) = $a"

((++a)) # C语言风格的前置自加.
echo "a (after ++a) = $a"

((--a)) # C语言风格的前置自减.
echo "a (after --a) = $a"

echo

########################################################
# 注意: 就像在C语言中一样, 前置或后置自减操作
#+ 会产生一些不同的副作用.

n=1
let --n && echo "True" || echo "False" # False
n=1
let n-- && echo "True" || echo "False" # True

# 感谢, Jeroen Domburg.
########################################################

echo

((t = a < 45 ? 7 : 11)) # C语言风格的三元操作.
echo "If a < 45, then t = 7, else t = 11."
echo "t = $t " # Yes!

echo

# ------------
# 复活节彩蛋!
# ------------
# Chet Ramey显然偷偷摸摸的将一些未公开的C语言风格的结构
#+ 引入到了Bash中 (事实上是从ksh中引入的, 这更接近些).
# 在Bash的文档中, Ramey将((...))称为shell算术运算,
#+ 但是它所能做的远远不止于此.
# 不好意思, Chet, 现在秘密被公开了.

# 你也可以参考一些 "for" 和 "while" 循环中使用((...))结构的例子.

# 这些只能够在Bash 2.04或更高版本的Bash上才能运行.

exit 0

目录
相关文章
|
3月前
|
缓存 物联网 Shell
Bash 学习摘录1
Bash 学习摘录
37 0
|
6月前
|
资源调度 Unix Shell
【bash指令全集合】最全教程-持续更新!
【bash指令全集合】最全教程-持续更新!
135 0
|
Shell Linux 芯片
第十章、认识与学习BASH
第十章、认识与学习BASH
88 0
|
Unix Shell Linux
关于 Bash 脚本中 Shebang 的趣事
关于 Bash 脚本中 Shebang 的趣事
|
存储 Shell 测试技术
开始你的bash/shell脚本编程
原文链接 I love bash 对于我自己来说,学习新框架或技术的最佳方式是同时获得实践经验,在本文中,你将自己通过编写代码来学习shell脚本的基础知识!本文包含语法,shell脚本的基础知识到中级shell编程,通过这篇文章你可以学习shell的相关知识,并且通过shell来实现Unix/Linux之间的接口 1_qo-oir60xdhic3wjqpu64g 介绍 您可能已经多次遇到过“脚本”这个词,但脚本的的含义是什么意思呢?简单的来说,脚本是包含一系列要执行的命令。
1268 0
|
Shell 算法 Apache
|
Shell Python C++