Linux Bash shell中的这些用法你都了解了吗? (一)
如何做一些个性化输出:
- echo
echo 是bash shell中的常见输出命令。但是echo可以实现带颜色的文本输出。用法如下:
echo -e "\e[1;31m This is red text \e[0m"
[1;31m This is red text [0m
这里-e
表示可以处理带有转义字符的输入 \e[1;31m
这个转义字符串把字体颜色设置成红色,\e[0m
把颜色进行重置
31是字体颜色代码。对于字体颜色有:
重置=0, 黑色=30, 红色=31, 绿色=32, 黄色=33, 蓝色=34, 品红色=35, 蓝绿色=36, 白色=37.
如果需要改变背景颜色,可以用下面来实现
echo -e "\e[1;42m Green Background \e[0m"
[1;42m Green Background [0m
对于背景颜色有
重置=0, 黑色=40, 红色=41, 绿色=42, 黄色=43, 蓝色=44, 品红色=45, 蓝绿色=46, 白色=47.
- printf printf可以在格式上做出更精确的控制,用法如下:
printf "%-5s %-10s %-4s\n" No Name Score
printf "%-5s %-10s %-4.2f\n" 1 Tom 80.2345
printf "%-5s %-10s %-4.2f\n" 2 Jack 79.3542
printf "%-5s %-10s %-4.2f\n" 3 Charles 75.5789
No Name Score
1 Tom 80.23
2 Jack 79.35
3 Charles 75.58
%s,%c,%d,%f 是替换符(s:string, c: character, d:int, f:float)学过c/c++的同学应该很容易理解这些
环境变量部分
- 如何查看一个进程相关的环境变量
cat /proc/$PID/environ
获取一个程序的的进程id可以用过pgrep
比如pgrep gedit
2. UID 是一个重要的环境变量,可以用来检查当前脚本是以一个root 用户还是一个普通用户运行的。
if [ $UID -ne 0 ]; then
echo "Non root user. Please run as root"
else
echo "Root user"
fi
Non root user. Please run as root
- SHELL 是一个标志当前我们正在使用那个shell的环境变量
echo $SHELL
/bin/bash
-
PS1 可以用来修改 bash shell的提示字符串
默认的bash shell 提示字符串是类似这样的"username@hostname:~"原来的PS1定义如下:‘PS1=′" 原来的PS1定义如下: `PS1='"原来的PS1定义如下:‘PS1=′{debian_chroot:+($debian_chroot)}\u@\h:\w$ '通过修改PS1我们可以做到这样的
PS1="这个帅帅的人输入了: "` -
定义一个函数来是实现增加一个参数到指定环境变量
prepend(){ [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1; }
-
从PS1和prepend这个函数中我们看到了如下形式的shell参数扩展
${parameter:+expression}
这个表达式的含义是如果变量parameter被设置且其值不是null,那么这个表达式被扩展成expression,即"${parameter:+expression}“被替换为"expression”
文件描述符
我们都知道在linux 中,文件描述符0,1,2被保留,并且有以下含义:
- 0: 标准输入
- 1:标准输出
- 2:标准错误
在shell编程中我们也经常用类似
cmd 2>stderr.txt 1>stdout.out
或者 cmd 2>&1 output.txt
或者 cmd >& output.txt
这些用法。
高级用法1: 但是如果我们如果急需要把数据重定向到一个文件,同时又需要把这部分数据作为标准输入提供给下一个命令,又该如何做呢?
比如我们想把ls 执行的结果输出到一个文件中,又想把ls输出的结果利用管道传给cat -n 命令。我们知道可以利用 ls > output.txt
输出到文件,也可以利用通过 ls | cat -n
把ls结果输入给cat。 但是 ls > output.txt | cat -n
这样的命令只能把ls的输出重定向到output.txt,却无法再作为cat命令的参数了。
答案是通过 tee
命令
ls | tee output.txt | cat -n
这时ls的输出会保存在output.txt中,又能通过命令cat命令输出到屏幕上。
高级用法2: 如何自定义文件描述符?
比如说我们想执行类似于cat file.txt
这种把文件作为输入的命令,文件名在带上路径的情况下会很长比如/etc/lib/software/…/a.conf,每次都写那么长的文件名很繁琐,我们可以定义一个文件描述符比如3来绑定文件,这样每次只需要写成cat >&3
了。
如何做呢?
答案是通过exec
命令。
通过exec
命令,我们可以创建只读文件描述符®,清空写文件描述符(w),追加写文件描述符(a+)。
- 只读权限文件描述符
exec 3<input.txt #创建文件描述符3 cat <&3 # 使用文件描述符3
- 清空写文件描述符
exec 4>output.txt #创建清空写文件描述符4 ls >&4 #使用文件描述符4
- 追加写文件描述符
exec 5>>log.txt #创建清空写文件描述符5 apache2 start >&5 #使用文件描述符5
关于函数的部分
在函数中如何接收传入的参数?
- $0:脚本名称
- $1:第一个参数
- $2:第二个参数
- $n:第n个参数
- “$@” 返回所有的参数,形式为 “$1” “$2” “$3” …
- “$*” 返回所有的参数,形式为 “$1c$2c$3”,这里c是IFS变量的第一个字符
- $? 返回命令执行的结果
"@"和"@" 和"@"和"*"的区别:
“$*” 是把所有参数作为一个单独的字符串返回.
一个利用"$@"的例子,定义一个repeat函数,这个函数的作用是重复执行指定命令,直到命令执行成功
repeat()
{
while true
do
$@ && return
done
}
或者更快的实现 repeat () { while :; do $@ && return ; done }
其用法为:repeat cmd parameter of the cmd
repeat weget -c http://www.example.com/test.tar.gz