@perkyoung
2015-07-12T14:35:34.000000Z
字数 3597
阅读 1817
运维
script.sh
#!/bin/bash
echo "the script starts now."
echo "Hi, $USER!"
echo
echo "I will now fetch you a list of connected users:"
echo
w
echo
echo "I'm setting two variables now."
export COLOUR="red"
COLOUR="black"
VALUE="9"
echo "this is stinrg : $COLOUR"
echo "and this is a number: $VALUE"
在终端中执行这个脚本的,父进程会创建一个子进程,在子进程中执行这个脚本的内容。当子进程退出时候,控制权再次交给父进程,所以在子进程中创建的变量都会失效。包括export是变量,或者export改变的原有的变量的值,都会失效。
如果想用一个脚本调用另外一个脚本,并且需要另外一个脚本中的变量值,就需要source ./script.sh
,这个意思是不创建进程,而是在当前脚本中执行,和sh中的'.'的意思是一样的,而且被调用的脚本也不需要有可执行权限。
#!/bin/bash
决定要启用的shell
脚本最好要在首部写上此脚本的作用,如果在其他行的关键部位也有注释,就更好了
调试整个脚本
sh -x ./script.sh
调试部分脚本
set -x
code..........
set +x
/etc/profile,/etc/inputrc,/etc/profile.d
这些配置文件应用到了所有用户。
/etc/profile,为每个用户设置环境信息,当用户第一次登陆时候运行
~/.bash_profile
用户其实需要增加针对自己的配置,或者更改默认设置。这时候就是这个文件了。这个文件一般也会执行 ~/.bashrc,~/.bash_login
~/.bash_login
这个文件包含了只有你在登陆系统的时候才执行的特殊设置,本机的ubuntu系统没有这个文件,一般情况下,在没有~/.bash_profile
的时候才会找这个文件,如果同时存在这两个文件,那一般情况下,在~/.bash_profile
中,也会执行了~/.bash_login
~/.profile
在没有~/.bash_profile, ~/.bash_login~
的情况下,才会读取这个文件
~/.bashrc
在大多数情况下,是使用非登陆shell的,比如你的桌面linux,打开终端,从来没有让亲输入过用户名密码吧;无需认证;同时他也会读取登陆时的配置文件,所以无需重复添加。一般系统中不存在/etc/bashrc
。这个文件中用户就可以自定义一些想立即生效的变量或者别名。利用xshell远程的ssh登陆时,会执行~/.bash_profile
,也会执行~/.bashrc
,如果复制一个xshell,仅会执行~/.bashrc
如何生效
重新连接系统或者source file这个配置文件。多数 shell 脚本在一个私有环境中执行:除非变量是父脚本 export 出来的,不然他们不会被子进程继承下来。
全局变量
全局变量或者环境变量存在于所有的shell当中,printenv或env可以输出他们
本地变量
set可以显示所有变量的列表,包括环境变量和函数
一般的变量只存在于当前shell,子shell不会知晓,
$full_name="perkyoung"
$bash
$echo $full_name
//该值为空,因为那个变量是本地变量
想让子shell知道,就需要导出该变量,export full_name,导出的变量就像环境变量一样,对子shell可见,但是子shell对该导出变量做的更改,不会影响父shell本身
$full_name="perkyoung"
$export full_name
$bash
$echo $full_name
perkyoung
$export full_name="liguoli"
$exit
$echo $full_name
perkyoung
sed '/errors/p' example #匹配包含errors的行并输出,但是会输出两次
sed -n '/errors/p' example #这个只输出了一次
sed '/errors/d' example #删除包含errors的行
sed '2,4d' example #删除2-4行
sed '3,$d' example #3-最后一行
sed '/a text/,/This/p' example #从``a text``到``This``的行
sed 's/erors/errors/g' example
sed 's/^/>/g' example #行首插入>
sed 's/$/EOL/g' example #行尾插入EOL
sed 's/erors/errors/g' -e 's/last/final/g' example
#!/bin/bash
if [ ! -f ./aaa ] ; then
echo "./aaa is not exist."
fi
LINENUM=`wc -l ./aaa`
echo $LINENUM # result is : 3 ./aaa
if test "$LINENUM" == "3" #字符串的比较,喜欢用test替代[]
then
echo "line num is 3"
fi
if test "$LINENUM" -eq "3" #因为LINENUM包括字母,所以-eq就会有语法错误,只能用==进行字符串的比较
then
echo "....."
fi
LINENUM=$(wc -l ./aaa | cut -f1 -d" ") #取一个命令行行的结果的另一种方法
echo $LINENUM #3
if test "$LINENUM" -eq "3" ; then #只要LINENUM是数字,那无论是否是引号,或者换成==,都正确
echo "...."
fi
if test $(whoami) == 'perkyoung'
then
echo "is perkyoung"
fi
#!/bin/bash
gender="192.168"
if [[ "$gender" =~ [0-9]{3}\.[0-9]+ ]] #两个双括号匹配
then
echo "yes"
fi
NAME="perkyong"
REG='.+y.+'
if [[ $NAME =~ $REG ]]
then
echo "yes"
fi
if ! grep $USER /etc/passwd 1>/dev/null #获取grep的返回状态,目测应该不是返回值,因为如果匹配到,返回值是0,取非之后是1,但是却没有走到下面的分支
then
echo "have NO the account"
fi
YEAR=`date +%Y`
if test $[$YEAR % 4] -eq "0" #在中括号种进行运算,如果是命令的话,可以用`或者小括号
then
echo "run nian"
else
echo "no run nian"
fi
if test $[$YEAR % 4] == "0" && (test $[$YEAR % 4] != "1" || ..... ) #将test换成[]也行,
then
echo "....."
fi
SPACE="anquan"
case $SPACE in
start)
echo "anquan"
;;
end)
echo "bu anquan"
;;
*)
echo "default"
;;
esac
echo -e "name\tage" #-e选项可以用来专业反斜杠
echo -n "input:" #-n选项不输出换行符
read name
$exec 100>./result #指定文件描述符给文件
$ls -l * >& 100 #文件内容输出到该文件
$cat ./test
hello world perkyoung
exec 7<&0
exec < ./test #test内容是
read name1 name2 name2
echo $name2 # hello
echo $name2 # world
echo $name3 # perkyoung
exec 7<&- $关闭文件描述符
#!/bin/bash
echo $(uname) #shell解释性语言,不会是别处后面的uname,输出系统自带的uname命令结果
num=1000
uname(){
echo "test!"
num=$[$num+1]
return 100
}
testvar()
{
local num=10
num=$[$num+1]
echo $num
}
uname #调用自身定义的uname函数
echo $? #获取返回值100
echo $num #uanme函数改变的是全局的num值
testvar
echo $num #testvar改变的是局部变量的num,对外界没有影响