快捷键
Ctrl+r快速查找历史命令Ctrl+l清理控制台屏幕
移动光标
Ctrl+a移动光标到行首Ctrl+e移动光标到行尾Alt+Left Arrow移动光标到上一个单词Alt+Right Arrow移动光标到下一个单词
删除字符
Ctrl+u删除光标之前的内容Ctrl+k删除光标之后的内容Ctrl+w删除光标前面的一个单词
进程
Ctrl+d退出。等同于exit命令Ctrl+z当前运行的程序后台运行。如果一步到位,可以在命令后面加&
重定向
- 执行时的错误信息输出到文件(
2>)
hello 2> log.error
$ cat log.error
-bash: hello: 未找到命令
- 执行时的所有信息都输出到文件(
&>)
echo hello &> log.info
$ cat log.info
hello
- 创建一个文件并写入内容(
> filename <<EOF)
cat > hello.sh << EOF
#!/bin/bash
echo hello
EOF
变量
变量赋值
- 执行结果保存到变量(
$()``)
var1=$(pwd)
var2=`pwd`
- 整数四则运算(
let)
let n=10-3+4/2
echo $n
9
变量引用
${var}大部分情况可省略为$var
str="hello world"
echo $str ${str}123
变量作用范围
- 默认只在当前shell中生效
$ str="hello world"
$ echo $str
hello world
$ bash
$ echo $str
$ exit
$ echo $str
hello world
- 四种执行模式运行
$ vim test.sh
#!/bin/bash
echo $str
$ chmod u+x test.sh
$ bash test.sh
$ ./test.sh
$ source test.sh
hello world
$ . test.sh
hello world
- 导出变量(
export),父进程定义的变量子进程可见。
$ export str
$ bash test.sh
hello world
$ source test.sh
hello world
- 移除变量(
unset)
$ unset str
$ echo $str
环境变量配置文件
- /etc/profile
- /etc/profile.d
- ~/.bash_profile
- ~/.bashrc
- /etc/bashrc
su - root 执行顺序
- /etc/profile
- ~/.bash_profile
- ~/.bashrc
- /etc/bashrc
su root 执行顺序
- ~/.bashrc
- /etc/bashrc
修改后的配置文件在当前Shell生效
source ~/.bashrc
环境变量
env查看命令$PATH命令的搜索路径$PS1bash提示符
预定义变量
$?上一个命令执行的错误码
$ ifconfig
$ echo $?
0
$ ifconfig eth
$ echo $?
1
$$当前进程ID
$ echo $$
26102
$0当前进程名
$ echo $0
-bash
位置变量 $1 $2 $3 ... $N
vim test.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12-DEFAULT_VALUE}
if [ -z ${12} ]
then
echo "NULL"
else
echo "NOT NULL"
fi
$ chmod u+x test.sh
$ ./test.sh 1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11 DEFAULT_VALUE
NULL
$ ./test.sh 1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
NOT NULL
- 位置值超过9后需要使用花括号
${N} - 没有传入值变量为空,可以给一个默认值
${N-DEFAULT_VALUE}
SHOW_LABELS=${1:-true}
数组
- 定义数组
ips=(10.0.0.1 10.0.0.2 10.0.0.3)
- 显示所有数组元素
$ echo ${ips[@]}
10.0.0.1 10.0.0.2 10.0.0.3
- 数组元素个数
$ echo ${#ips[@]}
3
- 数组取值
$ echo ${ips}
10.0.0.1
$ echo ${ips[0]}
10.0.0.1
$ echo ${ips[2]} ${ips[-1]}
10.0.0.3 10.0.0.3
引用
- 单引号(完全引用)
$ name=wjj
$ echo 'Hello $name!'
Hello $name!
- 双引号(不完全引用)
$ name=wjj
$ echo "Hello $name!"
Hello wjj!
- 反引号(执行命令)
$ echo `pwd`
/root
运算符
- 赋值运算符
$ let n=4+5
$ echo $n
9
$ ((n=4+5))
$ echo $n
9
$ ((n++))
$ echo $n
10
$ echo $((3+4))
7
- 算术运算符(+ - * / ** %)
$ expr 4 + 5
9
表达式
序列表达式 {START..END[..INCREMENT]}
$ echo {1..3}
1 2 3
$ echo {1..5..2}
1 3 5
$ echo {3..1}
3 2 1
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
echo {01..3}
01 02 03
echo file{1..3}.jpg
file1.jpg file2.jpg file3.jpg
if
判断变量为空-z
下面是判断 $1 和 $2 任意一个为空则为 True
if [ -z $1 ] || [ -z $2 ]; then
fi
判断文件是否存在-f
if [ -f $1 ]; then echo "file exist" fi
for
遍历数字范围
for i in {1..3}; do echo $i; done
1
2
3
函数
传入数组变量 "${VAR[*]}" 一定要加 "
f(){
arr=$1
}
ARR=(1 2 3)
f "${ARR[*]}"
虽然 echo "${ARR[*]}" 和 echo "${ARR[@]}" 的显示结果都一样,但传函数参数的效果确不一样。
测试代码
f(){
local app_name=$1
local platforms=$2
local version=$3
echo $app_name $version
for platform in $platforms
do
echo "Platform: $platform"
done
}
APP_NAME=yolo
PLATFORMS=(arm64 x86_64 i386)
VERSION=1.0.0
f $APP_NAME "${PLATFORMS[@]}" $VERSION
echo '----------------'
f $APP_NAME "${PLATFORMS[*]}" $VERSION
执行结果
yolo x86_64
Platform: arm64
----------------
yolo 1.0.0
Platform: arm64
Platform: x86_64
Platform: i386