1. version
bash --version
echo $BASH_VERSION
2. initalize
-
/etc/profile
The systemwide initialization file, executed for login shells -
/.bash_profile(/.bash_login, ~/.profile) <= Login shell
The personal initialization file, executed for login shells
It is sourced after the /etc/profile. If ~/.bash_profile doesn’t exist, bash will look for another user-defined file, ~./bash_login, and source it, and if ~./bash_login doesn’t exist, it will source the ~/.profile, if it exists. Only one of the three files will be sourced. -
.bashrc <= interactive shell
The individual per-interactive-shell startup file
set ENV variable. This file is automatically sourced every time a new or interactive bash shell or bash script starts.
配置shell
/etc/profile 所有用户环境信息,从/etc/profile.d中的配置文件收集shell设置
/etc/bashrc 运行bash shell的用户执行该文件,用户可在自己的.bashrc中overwrite该文件中设置的环境变量
~/.bash_profile 用户登录时执行一次,默认情况下,设置环境变量并执行.bashrc
~/.bashrc 用户登录或运行bash shell时读取该文件
~/.bash_logout 退出最后一个bash shell时执行
-
/etc/bashrc
Systemwide functions and aliases. -
~/.bash_logout
The individual login shell cleanup file, executed when a login shell exits
# bash环境配置:
- login shell,主要读取/etc/profile及~/.bash_profile
- non-login shell,主要读取~/.bashrc
3. Prompt
PS1='[\u@\h \W]\$'
PS1='[\u@\h \w \A #\#]\$ '
PS2=">"
3. Arithmetic Expansion
echo $[ 5 + 4 * 3 ] # 17
echo $(( 3 - 7 / 3 )) # 1
4. Array
declare -a friends=(Sheryl Peter Louise)
echo ${friends[0]} # Sheryl
echo ${friends[*]} # Sheryl Peter Louise
echo ${#friends[*]} # 3
5. Rediretion
Redirection Operator
What It Does
< filename
Redirects input
> filename
Redirects output
>> filename
Appends output
2> filename
Redirects error
2>> filename
Redirects and appends error
&> filename
Redirects output and error
>& filename
Redirects output and error (preferred way)
2>&1
Redirects error to where output is going
1>&2
Redirects output to where error is going
>|
Overrides noclobber when redirecting output
<> filename
Uses file as both standard input and output if a device file (from /dev)
6. read
read answer
read first last
read # $REPLY
read -a array
read -p prompt
read -r line # allows the input to contain a backslash
# input in 30s
read -p "please input your name: " -t 30 name
7. Arithmetic
declare -i x=017 # 15
x=2#101 # 5
x=8#17 # 15
x=16#b # 11
8. test
name=Tom
[ $name = [Tt]?? ]
echo $? # 1, don't allow wildcard expansion
[[ $name == [Tt]?? ]]
echo $? # 0
9. Variable
# local variable
declare name="Tom"
# global variable
export ORACLE_SID=ora11g
declare -x ORACLE_SID=ora11g
10. arguments
echo $1 $2 $3
echo $*
echo $# # the number of arguments
11. array
-
declare
declare -a array
array[key]=value
array=(val1 val2 … valn)
declare -a fruit=( apples pears plums ) -
access
${array[key]}
${array[0]} <=> ${array[@]:0:1} <=> $array
${array[@]} <=> ${array[*]}
${array[@]:0:2} <=> ${array[0]} ${array[1]}
${array[@]:2} <=> ${array[2]} … ${array[n]} -
eliminate
unset ${array[0]}
unset array -
length
${#array[@]}
${#array} <=> ${#array[0]} # length of first element
12. arithmetic
typeset -i num=5+4
declare -i num=5+4
13. control statement
if (( numeric expression ))
if [[ string expression ]]
while (( numeric expression ))
while [[ string expression ]]
until (( numeric expression ))
until [[ string expression ]]
for name in Tom Dick Harry
PS3=“Select an name from the menu:”
select name in Tom Dick Harry
14. 内置命令和外部命令
type -all pwd
command pwd # 强制将pwd当命令执行
cd //
pwd # //, here is built-in
/bin/pwd # /, here is command
enable -n pwd # 屏蔽built-in command pwd
pwd # /
15. Quote
hard quote: '', 屏蔽所有meta
soft quote: "", 屏蔽大部分meta,$`\除外
escape: \, 屏蔽其后紧随的meta, & * + ^ $ ` " | ?
~> a="b
> c
> "
~> echo $a --meta为\n,未在soft quote中,被解释为IFS
b c
~> echo "$a"
b
c
~> a=b\
> c\
>
~> echo $a --escape关闭CR
bc
~> echo "$a"
bc
awk '{print $0}' # hard quote
awk "{print \$0}" # soft quote
awk \{print\ \$0\} # escape
A=0
awk "{print \$$A}"
awk \{print\ \$$A\}
awk '{print $'$A'}'
awk '{print $'"$A"'}'
16. IFS: Internal Field Seperator
~> set | grep IFS
IFS=$' \t\n'
17. null value & unset
str=
var=${str=expr}
echo $var # null
echo $str # null
unset str
var=${str=expr}
echo $var # expr
echo $str # expr
18. fork, source, exec
fork: 产生子进程,子进程执行完毕,返回父进程。
source:不产生子进程,在当前shell中执行,执行完成后,环境变量可能被改变
exec:It replaces the shell. No new process is created.
19. {}, (), $(()), $(), ${}
(): nested sub-shell
{}: non-named command group
$( ) <=> # 后者在unix shell中移植性较高
${ } 变量替换
${file#*/} # dir1/dir2/dir3/my.file.txt
${file##*/} # my.file.txt
${file#*.} # file.txt
${file##*.} # txt
${file%/*} # /dir1/dir2/dir3
${file%%/*} # null
${file%.*} # /dir1/dir2/dir3/my.file
${file%%.*} # /dir1/dir2/dir3/my
# 截取字符串
${file:0:5} # /dir1
${file:5:5} # /dir2
# 字符串替换
${file/dir/path} # /path1/dir2/dir3/my.file.txt
${file//dir/path} # /path1/path2/path3/my.file.txt
# 变量状态 unset, null, non-null
${file-my.file.txt} # if file unset, my.file.txt
${file:-my.file.txt} # if file unset/null, my.file.txt
${file+my.file.txt} # if file null/non-null, my.file.txt
${file:+my.file.txt} # if file non-null, my.file.txt
${file=my.file.txt} # if file unset, my.file.txt, and file=my.file.txt
${file:=my.file.txt} # if file unset/null, my.file.txt, and file=my.file.txt
${file?my.file.txt} # if file unset, STDERR my.file.txt
${file:?my.file.txt} # if file unset/null, STDERR my.file.txt
# 字符串长度
${#file}
# 数组长度
${#A[@]}
$(( )) 整数计算
a=5; b=7; c=2
echo $(( $a - $b * $c)) # -9
20. pwd (bash)
pwd -P: 真实路径(等效于set -o physical)
pwd -L: 软连接路径(默认开启)
21. 防止文件被overwrite
set -o noclobber
$ cat file.out
1
$ set -o noclobber
$ echo 2 > file.out
bash: file.out: cannot overwrite existing file
type: bash built-in
-t: (file, alias, buitin)
-p: path
-a: all
type ls
type -t ls
type -t passwd
type -p passwd
type -a passwd
type cd
子程序继承父程序的环境变量,但不能继承父程序的自定义变量
read -p "Please enter your name: " -t 30 name
echo $name
declare
-a: array
-i: integer
-x: export
-r: readonly
declare -i num=100+200+300
ulimit -a
ulimit -f 10240 # 不能创建超过10M的文件
变量内容删除,替换
${PATH#*/bin:} # 头端最短删除
${PATH##*/bin:} # 头端最长删除
${PATH%:*bin} # 尾端最短删除
${PATH%%:*bin} # 尾端最长删除
a="123abc123"
echo ${a/123/456} # 456abc123
echo ${a//123/456} # 456abc456
# 登录提示信息
/etc/motd
# bash配置
login shell: 由tty1~tty6登录,需要输入用户名和密码,此时取得的bash为login shell
non-login shell: 不需要登录就能取得的bash。1) X window登录后,启动的终端 2) 子程序
1) /etc/profile (login shell才会读)
自动呼叫/etc/inputrc; /etc/profile.d/*.sh; /etc/sysconfig/i18n
2) ~/.bash_profile(login shell才会读)
~/.bash_profile
~/.bash_login
~/.profile
bash依顺序读取上面三个文件,允许文件不存在
3) ~/.bashrc (non-login shell会读)
stty: setting tty
stty erase ^h # ctrl + h 删除
stty erase ^? # Backspace 删除
# $-: set配置值
echo $- # himBH
cut -d'delimeter' -f fields
cut -c characters
echo $PATH | cut -d ":" -f 2,4-6
export | cut -c 12-
cat /etc/passwd | sort -t ":" -k 3
cat /etc/passwd | sort -t ":" -k 3 -n
last | tr '[a-z]' '[A-Z]'
cat /etc/passwd | tr -d ":"
cat dos.txt | tr -d '\r'
col -x: output multiple spaces instead of tabs
cat /etc/manpath.config | col -x | cat -A
col -b: do not ouput any backspaces
man col | col -b > /tmp/col.man
head -3 /etc/passwd /etc/shadow
join -t ":" /etc/passwd /etc/shadow | head -3
# 根据group ID 链接
join -t ":" -1 4 /etc/passwd -2 3 /etc/group
# 文件行合并,分隔符TAB,其他分割符使用-d指定
paste /etc/passwd /etc/shadow
# TAB转换为空格,默认8个
grep '^MANPATH' /etc/manpath.config | head -3 | cat -A
grep '^MANPATH' /etc/manpath.config | head -3 | expand -t 4 | cat -A
# split
split -b 1m myfile.txt myfile