# 1. shell 变量与常见符号

## 变量

运行shell时，会同时存在三种变量：

1. 局部变量 局部变量在脚本或命令中定义，仅在当前shell实例中有效，其他shell启动的程序不能访问局部变量。
2. 环境变量 所有的程序，包括shell启动的程序，都能访问环境变量，有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3. shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量，有一部分是局部变量，这些变量保证了shell的正常运行

### 声明即用

```bash
a=2
b="123"
```

调用 ${varName}或者 $varName

```bash
echo $b
echo ${a}
```

### 只读变量

```bash
param=123
readonly param
param=1
```

运行

```bash
./1.sh:行3: param: 只读变量
```

### 删除变量

```bash
unset varName
```

* unset不能删除只读变量
* 删除后不能再次使用

```bash
a=123
unset a
echo $a
```

运行

```
没有任何输出内容
```

## 传递参数

### 常见变量

* $?:判断上一个语句是否成功
* $0:执行脚本文件名称
* $1:第1个参数
* $n:第n个参数
* $\*:参数分别是什么
* $@:与 $\*相同，但是使用时加引号，并在引号中返回每个参数。
* $#:参数个数
* $$:脚本当前的进程号

### 传递参数示例

demo1.sh

```bash
echo "脚本文件名称:$0"
echo "第1个参数:$1"
echo "所有的参数:$*"
echo "参数个数:$#"
```

赋予执行权限

```
chmod u+x demo1.sh
```

执行

```bash
./demo1.sh param2 1 2 3
```

输出结果

```
脚本文件名称:./demo1.sh
第1个参数:param2
所有的参数:param2 1 2 3
参数个数:4
```

## 符号

### 常见符号

#### `>`  :向目标文件写入内容

* 会覆盖掉原来的内容
* 例子:向文件1.txt写入hello world字符串

  ```bash
    # 直接在bash中可运行
    echo hello world > 1.txt
  ```

#### `>>` :向目标文件尾部插入内容

* 在源文件尾部追加内容
* 例子:向文件1.txt增加一行hello world字符串

  ```bash
    # 直接在bash中可运行
    echo hello world >> 1.txt
  ```

#### `;` :执行多条指令

* 例子:追加一行内容,然后显示文件当前的内容

  ```bash
    # 直接在bash中可运行
    echo hello world >> 1.txt ; cat 1.txt
  ```

#### `|` :管道符

* 将上一条命令的处理结果传给下一个命令处理
* 例子:将cat结果传给wc命令统计行数

  ```bash
    # 直接在bash中可运行
    # 最后一个字母为小写的L
    cat 1.txt | wc -l
  ```

#### `&&` :执行多条命令

* 前一条命令出错,会阻塞后续命令执行
* 例子:向1.txt追加一行内容 再查看其行数

  ```bash
    # 直接在bash中可运行
    echo str >> 1.txt && wc -l 1.txt
  ```

#### `||` :执行多条命令

* 前一条命令出错才会执行后续指令
* 例子:向1.txt追加一行内容出错 ,再查看其内容

  ```bash
    # 直接在bash中可运行
    echo3 str >> 1.txt || cat 1.txt
  ```

#### `""` :能够输出变量值

* 能够解析字符串中的 $varName 变量
* 例子:输出hello

  ```bash
  # 编写demo3.sh

    a="hello"
    echo "$a"
  ```

#### `''` :不能够输出变量值

* 不够解析字符串中的 $varName 变量
* 例子:不能输出hello

  ```bash
  # 编写demo3.sh

    a="hello"
    echo '$a'
  ```

  输出结果为:$a

#### ` `` ` :输出命令结果

* 例子:输出当前的日期
* date命令可获取当前日期

  ```bash
  echo `date`
  ```

#### `2>/dev/null` :错误输出到无底洞

* 命令执行错误则不会出现错误提示
* 执行正确才会有输出结果
* 例子

  ```bash
  # 执行
  echo1 123
  # 正常错误输出
  bash: echo1: 未找到命令
  # 使用无底洞
  echo1 123 2>/dev/null
  # 没有任何内容输出
  ```

#### `1>/dev/null` :正确输出到无底洞

* 命令执行正确则不显示执行结果
* 执行错误才会有错误提示内容&#x20;
* 例子

  ```bash
  # 执行
  echo 123
  # 正常输出
  123
  # 使用无底洞
  echo 123 1>/dev/null
  # 没有任何内容输出
  ```

## 字符串

字符串可以用**单引号**，也可以用**双引号**，也可以**不用引号**

### 单引号

```bash
str='hello world $$ $a'
echo $str
```

输出

```
hello world $$ $a
```

* 单引号里的任何字符都会原样输出
* 变量无效
* 不能单独出现一个引号(加上反斜杠转义也不行),只能成对出现
* 可用于字符串拼接

### 双引号

```bash
str='sugar'
echo "my name is $str"
```

输出

```
my name is sugar
```

* 双引号里可以有变量
* 双引号里可以出现转义字符

### 字符串拼接

```bash
name="sugar"
str1="hello, "$name" !"
str2="hello, $name !"
str3='hello, '$name' !'
str4='hello, $name !'
echo $str1
echo $str2
echo $str3
echo $str4
```

输出

```
hello, sugar !
hello, sugar !
hello, sugar !
hello, $name !
```

### 获取字符串长度

```bash
str="abcdefg"
echo "${#str}"
```

输出

```
7
```

### 截取字符串

```bash
str="hello world"
echo ${str:2:4}
```

输出

```
llo
```

## 数组

* 只支持一维数组
* 没有限定数组大小
* 可以不使用连续的下标，而且下标的范围没有限制。

### 数组声明格式

```bash
arrName=(v0 v1 v2 v3)
```

等价

```bash
arrName=(
  v0
  v1
  v2
  v3
)
```

等价

```
arrName[0]=v0
arrName[1]=v1
arrName[2]=v2
arrName[3]=v3
```

### 数组调用格式

```bash
${arrName[index]}
```

读取所有元素

```bash
${arrName[@]}
```

### 数组长度

```bash
length=${#arrayName[@]}
# 或者
length=${#arrayName[*]}
```

### 数组使用示例

```bash
arr1=(1 2 3 4 5)
arr2=("A" 'b' 'c' 3)
arr3=(
 1
 2
 3
)

echo "${arr1[0]}"
echo ${arr2[1]}
echo ${arr3[2]}

echo  "arr1长度为:${#arr1[*]}"
echo  "arr2长度为:${#arr2[@]}"
```

运行输出

```
1
b
3
arr1长度为:5
arr2长度为:4
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sugar-at.gitbook.io/blog-article/shell/1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
