8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
打开终端后,就会出现一个提示符号,# 表示超级用户 (root user) ,$ 表示普通用户,超级用户是 Linux 系统中权限最高的用户
shell脚本通常以 #! 起始,如1
/bin/bash 是Bash的路径
运行脚本的两种方式:将脚本作为命令行参数
将脚本作为具有执行权限的可执行文件1
2
3
4
5
6
7$ sh script.sh
# 2
$ chmod a+x script.sh
$ ./script.sh # 使用相对路径
$ /root/home/script.sh # 使用绝对路径
最终执行的逻辑会查找文件中的 /bin/bash ,并在内部执行如下1$ /bin/bash script.sh~/.bashrc 文件:包含定义诸如提示文本、颜色等各类设置的一组命令
~/.bash_history 文件:用于保存用户执行过的命令
在 Bash 中使用分号或换行符来分隔每个命令,如1
2
3
4
5
6
7
8cmd1; cmd2
# 2
cmd1
cmd2
使用 # 用于注释
终端打印
echo、printf
echo
终端作为交互式工具,用户可以通过它与shell环境进行交互,echo 命令用于终端打印的基本命令1
2
3
4
5
6
7
8
9
10
11# 使用双引号,OK
$ echo "hello world"
hello world
# 不使用双引号,OK
$ echo hello world
hello world
# 使用单引号,OK
$ echo 'hello world'
hello world
在双引号中打印特殊字符需要在字符前加转义字符 ,如1
2$ echo "hello world!"
hello world
在shell脚本中,可通过设置 set +H 来显示 !,如1
2
3
4
5# set_h.sh
set +H
echo "hello world!"
在使用单引号的情况下,若字符串包含变量 $var,则原样打印,如1
2$ echo 'hello world $var'
hello world $var
printf
printf 使用的参数和C语言中的 printf 函数一样
格式:printf FOMART_STR STR1$ printf "hello world"
可用于格式化输出,如1
2
3
4
5# printf.sh
printf "%-5s %-10s %-4sn" No Name Mark
printf "%-5s %-10s %-4.2fn" 1 John 89.999
执行输出1
2
3$ ./printf.sh
No Name Mark
1 John 90.00
变量和环境变量
在 Bash 中,每一个变量都是字符串
使用 env 命令查看当前终端进程所使用到的环境变量,如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20$ env
TMPDIR=/var/folders/1n/8t5fdjrd4mj1qn_13qwzcny80000gn/T/
__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0
SHELL=/bin/zsh
HOME=/Users/a2htray
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
LOGNAME=a2htray
XPC_SERVICE_NAME=0
USER=a2htray
XPC_FLAGS=0x0
LC_CTYPE=en_US.UTF-8
LESS=-R
LSCOLORS=Gxfxcxdxbxegedabagacad
SHLVL=1
ZSH=/Users/a2htray/.oh-my-zsh
TERM_PROGRAM=vscode
TERM_PROGRAM_VERSION=1.30.1
LANG=en_US.UTF-8
TERM=xterm-256color
_=/usr/bin/env
一个变量可通过以下方式进行赋值,如1
2
3
4# 等号两边不能有空格,正确
var=value # 赋值操作
# 错误
var = value # 判断相等操作
如需打印变量,在变量名前加 $,如1
2
3
4
5
6
7
8
9$ var=value
$ echo $var
# 或者
$ echo ${var}
# 在打印命令中引用该变量
$ echo "the ${var} of world is the $var"
the value of world is the value
额外
使用 #,可获取字符串的长度1
2
3
4
5
6
7
8
9
10
11
12# 获取字符串长度
$ var=value
$ length=${#var}
$ echo ${#var} $length
5 5
# 识别当前的shell版本
$ echo $SHELL
/bin/zsh
# 或者
$ echo $0
/bin/zsh
根据 root 用户的 UID 为 0 可判断当前用户是否为 root用户1
2
3
4
5
6
7
8
9
10
11# is_root.sh
set +H
if [ $UID -ne 0 ]; then
echo "non root"
else
echo "root"
fi
echo "$UID"
执行输出1
2
3$ ./is_root.sh
non root
501
通过shell进行数学运算
可以使用 let、(())、[] 执行基本的算数操作,进行高级运算时,可使用expr或bc1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#operation.sh
#!/bin/bash
# nu1与nu2均为字符串
nu1=5
nu2=6
let nu1++ # nu1自加1
let nu2-- # nu2自减1
echo $nu1 $nu2
# let简写形式
let nu1+=7 # nu1加7
let nu2-=2 # nu2减2
echo $nu1 $nu2
# 使用[]
result1=$[ nu1 + nu2 ]
echo $result1
# 使用(())
result2=$(( nu1 + nu2 ))
echo $result2
# 使用expr
result3=$(expr $nu1 + $nu2)
result4=`expr 3 + 4`
echo $result3 $result4
上述操作只适用于整数,若需浮点数支持,则使用bc
文件描述符和重定向
>、>>
文件描述符是与文件输入、输出相关联的整数,最常见的文件描述符是标准输入stdin、标准输出stdout与标准错误stderr数值描述符说明0stdin标准输入
1stdout标准输出
2stderr标准错误
使用>,通过截取的方式,将输出文本存储到文件tmp.txt中,tmp.txt文件中的内容将被清空1$ echo "hello world" > tmp.txt
使用>>,tmp.txt文件不会被清空,而是以追加到现有文件的尾部1$ echo "hello world" >> tmp.txt
当使用重定向操作符时,重定向的内容不会出现在终端,而是直接导入文件
重定向操作符的默认是标准输出,若希望使用特定的描述符,必须将描述符置于操作符之前1
2
3
41> # 等价于 >
2>
1>> # 等价于 >>
2>>
成功与不成功命令的区别在于是否返回 0 :成功返回 0 ,不成功返回非 0 ,返回值可通过特殊变量 $? 获得1
2
3
4
5$ ls +
ls: +: No such file or directory
$ echo $?
1
$ ls + 2> tmp.txt # 使用描述符将标准错误导入tmp.txt1
2
3
4# 可以将stderr单独导入到一个文件,stdin单独导入到另一个文件
$ cmd 1> in.txt 2> err.txt
# 将stderr转换成stdout,导入到同一个文件
$ cmd 2>&1 all.txt
常用作法是将stderr重定向到 /dev/null 设备文件,该文件收到的任何数据都将丢弃
管道符|
使用 tee 命令结合管道符|,一方面可以将数据重定向到文件,另一方面还可以提供一份重定向数据的副本作为后续命令的 stdin ,如1
2
3# tee 接受stdout的作为输入
$ ls + | tee out.txt
ls: +: No such file or directory
补充
借助重定向,可以像使用stdin那样从文件中读取数据1$ cmd < FILE
使用别名
使用alias命令,如果别名已经存在,会将原别名取代1
2
3$ alias new_command='command sequence'
# 为保持别名持续有效,将其写入~/.bashrc
$ echo new_command='command sequence' > ~/.bashrc
获取终端信息
tput、stty是两款终端处理工具1
2
3
4# 基本用不到
tput cols # 输出当前终端列数
tput lines # 输出当前终端行数
tput longname # 输出当前终端名
获取、设置日期和延时
使用date命令1
2
3
4
5
6
7
8
9# date.sh 获取程序运行的时间
#!/bin/bash
start=$(date +%s)
cmd
cmd
...
end=$(date +%s)
duration=$((end - start))
使用sleep生成延时1$ sleep 5 # 延时5秒
调试脚本set -x
运行带 -x 的脚本能打印出所执行的每一行命令以及当前状态
在脚本文件中可心使用 set 命令进行设置命令描述set -x在执行时显示参数和命令
set +x禁止调试
set -v当命令进行读取时显示输入
set +v禁止打印输入
技巧,通过设置变量决定是否开启调试1
2
3
4
5
6
7# debug.sh
#!/bin/bash
# if statement
if [ $_DEBUG == "on" ]; then
echo "debug"
fi
调用1$ _DEBUG=on ./debug.sh
将 #!/bin/bash 修改为 #!/bin/bash -xv ,这样就不用其他选项就可以启用调试功能
函数与参数
定义函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#!/bin/bash
function func1()
{
echo "func1"
}
func1
func2()
{
echo "func2"
}
func2
function func3()
{
echo $1
}
func3 "func3"$1 是第一个参数
$2 是第二个参数
$n 是第n个参数
$@ 扩展成”$1” “$2” “$3”等
$* 扩展成”$1c$2c$3”等
函数也能像环境变量一样用export导出,则函数的作用域可以扩展到子进程中1export -f fname
读取命令序列输出
输入通常是通过stdin或参数传递给命令,输出要么出现在stderr,要么出现在stdout1cmd1 | cmd2 | cmd3
cat -n 将输出加上行号
读取命令序列的输出1
2
3
4
5cmd_output=$(ls | cat -n)
echo $cmd_output
# 或者
cmd_output=`ls | cat -n` # 使用反引用
echo $cmd_output1
2
3
4
5
6
7
8
9
10
11
12$ cat text.txt
1
2
3
$ out=$(cat text.txt)
1
2
3
$ out="$(cat text.txt)"
1
2
3
读取字符
下面语句从输入中读取n个字符并存入变量variable_name1read -n number_of_chars variable_name1
2
3
4
5$ 使用定界符:
$ read -d ":" var
hello:
$ echo $var
hello
字段分隔符和迭代器
IFS:内部字段分隔符,默认值为空白字符(换行符、制表符或空格)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# ifs.sh
#!/bin/bash
data="name,gender,age,location"
oldIFS=$IFS
IFS=,
# for循环不错
for item in $data;
do
echo Item: $item
done
IFS=$oldIFS
比较与测试
文件系统相关条件作用[ -f $var ]正常文件名或路径,返回真
[ -x $var ]文件可执行,返回真
[ -d $var ]正常目录,返回真
[ -e $var ]文件存在,返回真
[ -c $var ]一个字符设备文件的路径,返回真
[ -b $var ]一个块设备文件路径,返回真
[ -w $var ]可写,返回真
[ -r $var ]可读,返回真
[ -L $var ]符号链接,返回真
字符串比较条件作用[[ $str1 = $str2 ]]相等为真
[[ $str1 == $str2 ]]相等为真
[[ $str1 != $str2 ]]不相等为真
[[ $str1 > $str2 ]]大于
[[ $str1 < $str2 ]]小于
[[ -z $str1 ]]字符串包含空格字符,返回真
[[ -n $str1 ]]非空字符串,返回真
使用逻辑运算符将代码简洁一点,减少if else1
2[ condition ] && action # 如果为真则执行
[ condition ] || action # 如果为假则执行
结合多个条件进行测试-a: 逻辑与
-o: 逻辑或1
2
3
4# 0 < $var and $var < 10
[ $var -gt 0 -a $var -lt 10 ]
# $var < 0 or $var > 10
[ $var -lt 0 -o $var -gt 10 ]