#!/bin/bash
set -x
WR="account >"
while read line
do
WR="$WR>"" >""$line>"
done<a.txt
echo $WR [/code]
<p>最终我们看到输出的结果就是我们期待的 account a b c d #e f g</p>
+ WR='account '
+ read line
+ WR='account a'
+ read line
+ WR='account a b'
+ read line
+ WR='account a b c'
+ read line
+ WR='account a b c d'
+ read line
+ WR='account a b c d #e'
+ read line
+ WR='account a b c d #e f'
+ read line
+ WR='account a b c d #e f g'
+ read line
+ echo account a b c d '#e' f g
account a b c d #e f g
然后我们使用管道和while的方式进行读入,但是得到的结果却不是我们期望的
#!/bin/bash
set -x
WR="account >"
grep -v ^# a.txt | while read line
do
WR=${WR}" >"${line}
done
echo $WR
最终的输出为:
+ WR='account '
+ grep -v '^#' a.txt
+ read line
+ WR='account a'
+ read line
+ WR='account a b'
+ read line
+ WR='account a b c'
+ read line
+ WR='account a b c d'
+ read line
+ WR='account a b c d f'
+ read line
+ WR='account a b c d f g'
+ read line
+ echo account
account
#!/bin/bash
set -x
WR="account >"
for line in `grep -v ^# a.txt`
do
WR=${WR}" >"${line}
done
echo $WR
最终的输出结果我们所期望的。
+ WR='account '
++ grep -v '^#' a.txt
+ for line in '`grep -v ^# a.txt`'
+ WR='account a'
+ for line in '`grep -v ^# a.txt`'
+ WR='account a b'
+ for line in '`grep -v ^# a.txt`'
+ WR='account a b c'
+ for line in '`grep -v ^# a.txt`'
+ WR='account a b c d'
+ for line in '`grep -v ^# a.txt`'
+ WR='account a b c d f'
+ for line in '`grep -v ^# a.txt`'
+ WR='account a b c d f g'
+ echo account a b c d f g
account a b c d f g
#!/bin/bash
set -x
declare -x WR="account >"
grep -v ^# a.txt | ( while read line
do
WR=${WR}" >"${line}
done
echo $WR )
得到结果如下:
+ declare -x 'WR=account '
+ grep -v '^#' a.txt
+ read line
+ WR='account a'
+ read line
+ WR='account a b'
+ read line
+ WR='account a b c'
+ read line
+ WR='account a b c d'
+ read line
+ WR='account a b c d f'
+ read line
+ WR='account a b c d f g'
+ read line
+ echo account a b c d f g
account a b c d f g
#先看看更新数据的格式,将左边一列替换为右边一列,只有左边一列的删除,下面数据放入update.user.txt
tf twoFile
西安电子科技大学 西军电
西安交大 西安交通大学
北京大学
cat update.user.txt | while read src dst
do
if [ ! -z "${src}>" -a ! -z "${dst}>" ]
then
sql="update test.user set name='${dst}' where name='${src}'>"
fi
if [ ! -z "${src}>" -a -z "${dst}>" ]
then
sql="delete from test.user where name='${src}'>"
fi
$MYSQL -e "$sql>"
done
#!/bin/bash
echo "File Name : $0 >"
echo "First Parameter : $1 >"
echo "Second Parameter : $2 >"
echo "All Parameter : $@ >"
echo "All Parameter : $*>"
echo "Total Number of Parameter $# >"
echo "The Shell of the process ID is : $$>"
运行结果:
$ ./test.sh Dave Abby
File Name : ./test.sh
First Parameter : Dave
Second Parameter : Abby
All Parameter : Dave Abby
All Parameter : Dave Abby
Total Number of Parameter 2
The Shell of the process ID is : 2752
$ echo $? #查看./test.sh 退出状态。一般情况下成功返回0 ,失败返回-1
0
$ ./test.sh
Hello
Hello
Hello
World
Hello
./test.sh : line 13 : var: message
Shell的if语句
if语句通过关系运算符判断表达式的真假来决定执行那个分支,Shell有三种if语句。
if … fi 语句
if … else … fi 语句
if … elif … else … fi 语句
if … fi 语句的语法
if [ expression ]
then
Statement(s) to be executed if expression is true
fi
**注意:**expression 和方括号之间必须有空格。否则会有语法错误示例:
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a == b>"
fi
if [ $a != $b ]
then
echo "a! = b>"
fi
if … else … fi语句语法
if [ expression ]
then
Statement(s) to be executed if expression is true
else
Statement(s) to be executed if expression is not true
fi
示例:
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a == b>"
else
echo "a! = b>"
fi
if … elif …fi语句语法
if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statements to be executed if expression not is true
fi
示例:
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a == b>"
elif [ $a -gt $b ]
then
echo "a > b>"
elif [ $a -lt $b ]
then
echo "a < b>"
else
echo "None of the condition met>"
fi
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo "a == b>"
else
echo "a != b>"
fi
if [ $a -ne $b ]
then
echo "a != b>"
else
echo "a == b>"
fi
if [ $a -gt $b ]
then
echo "a > b>"
else
echo "a < b>"
fi
if [ $a -lt $b ]
then
echo "a < b>"
else
echo "a > b>"
fi
if [ $a -ge $b ];then echo "a > b>" ;else echo "a < b>" ;fi
if [ $a -le $b ];then echo "a < b>" ;else echo "a > b>" ;fi
布尔运算符
示例:
#!/bin/bash
a=10
b=20
if [ ! $a -eq $b ]; then echo "a == b>" ; else echo "a != b>" ; fi
if [ $a -lt $b -o $b -gt $a ]; then echo "a < b>" ; else echo "a > b>" ; fi
if [ $a -le $b -a $b -ge $a ]; then echo "a < b>" ; else echo "a > b>" ; fi
字符串运算符
示例:
#!/bin/bash
a="abc>"
b="edf>"
if [ ! $a = $b ]; then echo "a != b>" ; else echo "a == b>" ; fi
if [ $a != $b ]; then echo "a != b>" ; else echo "a == b>" ; fi
if [ -z $a -o -z $b ]; then echo "string length isn't zero>" ;
else echo "string length is zero>" ; fi
if [ -n $a -a -n $b ]; then echo "string length is zero>"
else echo "string length isn't zero>" ; fi
if [ $a -a $b ];then echo "string length is zero>"
else echo "string length isn't zero>" ; fi
文件测试运算符
文件测试运算符用于检测文件的各种属性
示例:
#!/bin/bash
if [ -b $1 ]; then echo "$1 is block file>" ; else echo "$1 is not block file>" ; fi
if [ -c $1 ]; then echo "$1 is str file>" ; else echo "$1 is not str file>" ; fi
if [ -d $1 ]; then echo "$1 is directory file>" ; else echo "$1 is not directory file>" ; fi
if [ -f $1 ]; then echo "$1 is ordinary file>" ; else echo "$1 is not ordinary file>" ; fi
if [ -g $1 ]; then echo "$1 SGID bit>" ; else echo "$1 not SGID bit>" ; fi
if [ -k $1 ]; then echo "$1 Sticky bit>" ; else echo "$1 not Sticky not bit>" ; fi
if [ -p $1 ]; then echo "$1 is pipe file>" ; else echo "$1 is not pipe file>" ; fi
if [ -u $1 ]; then echo "$1 SUID bit>" ; else echo "$1 not SUID bit>" ; fi
if [ -r $1 ]; then echo "$1 is read file>" ; else echo "$1 is not read file>" ; fi
if [ -w $1 ]; then echo "$1 is write file>" ; else echo "$1 is not write file>" ; fi
if [ -x $1 ]; then echo "$1 is execute file>" ; else echo "$1 is not execute file>" ; fi
if [ -s $1 ]; then echo "$1 is not zero>" ; else echo "$1 is zero>" ; fi
if [ -e $1 ]; then echo "$1 exists>" ; else echo "$1 not exists>" ; fi
运行结果:
$ ./test.sh test.sh
test.sh is not block file
test.sh is not str file
test.sh is not directory file
test.sh is ordinary file
test.sh not SGID bit
test.sh not Sticky not bit
test.sh is not pipe file
test.sh not SUID bit
test.sh is read file
test.sh is write file
test.sh is execute file
test.sh is not zero
test.sh exists
[关于SUID,SGID,Sticky的属性请参考:](<a href="../../Linux/2015-05/116982.htm">http://www.linuxidc.com/Linux/2015-05/116982.htm</a>)
#!/bin/bash
#Usage: user input a charector, program shows the different result.
#Author: Alfred Zhao
#Creation: 2015-05-06
#Version: 1.0.0
#1.Input 'Y' or 'N'
read -p "Input (Y/N)>" input
[ "$input>" == "Y>" -o "$input>" == "y>" ] && echo -e "you choice is: $inputn>" && exit 0
[ "$input>" == "N>" -o "$input>" == "n>" ] && echo -e "you choice is: $inputn>" && exit 0
echo -e "I don't know what your choice is>" && exit 0
2.分支判断
两种常用的分支判断:if…else…fi分支判断,case…esac分支判断。
练习2:将练习1中的代码改写为if分支判断,使程序的执行逻辑更直观。
考查:==,||
if[]; then
…
elif[]; then
…
else
…
fi
#!/bin/bash
#Usage: user input a charector, program shows the different result.
#Author: Alfred Zhao
#Creation: 2015-05-06
#Version: 1.0.1
#1.Input 'Y' or 'N'
read -p "Input (y/n)>" input
if [ "$input>" == "Y>" ] || [ "$input>" == "y>" ]; then
echo -e "you choice is: $inputn>"
exit 0
elif [ "$input>" == "N>" ] || [ "$input>" == "n>" ]; then
echo -e "you choice is: $inputn>"
exit 0
else
echo -e "I don't know what you choice is.n>"
exit 0
fi
练习3:用分支判断来辨别参数1的输入是否合法。
考查:$0,$1
#!/bin/bash
#Usage: To judge $1's identity. Aha, Only Alfred is ok.
#Author: Alfred Zhao
#Creation: 2015-05-07
#Version: 1.0.0
if [ "$1>" == "Alfred>" ]; then
echo -e "Authorization Successful! n>"
exit 0
elif [ "$1>" == ">" ]; then
echo -e "Waring: Authorization is null! ex> {$0 Username}n>"
exit 0
else
echo -e "Waring: Only Alfred can be authorized. ex> {$0 Alfred}n>"
exit 0
fi
练习4:用case判断改写练习3.
考查:case…esac判断
#!/bin/bash
#Usage: To judge $1's identity. Aha, Only Alfred is ok.
#Author: Alfred Zhao
#Creation: 2015-05-07
#Version: 1.0.1
case "$1>" in
"Alfred>")
echo -e "Authorization Successful! n>"
;;
">")
echo -e "Waring: Authorization is null! ex> {$0 Username}n>"
;;
*)
echo -e "Waring: Only Alfred can be authorized. ex> {$0 Alfred}n>"
;;
esac
3.循环结构
while do done, until do done(不定循环)
练习5:输入名字直到输入的名字是“Alfred”为止。
考查:while do done
#!/bin/bash
#Usage: Input the name until it is "Alfred>".
#Author: Alfred Zhao
#Creation: 2015-05-07
#Version: 1.0.0
while [ "$name>" != "Alfred>" ]
do
read -p "Please Input your name: >" name
done
echo -e "nWelcome, My friend, Alfred.n>"
而如果是使用until do done,
只需要修改 while [ “$name>” != “Alfred>” ]为 until [ “$name>” == “Alfred>” ]
练习6:计算1+2+3+…+num的结果
考察:正则
#!/bin/bash
#Usage: Calculate the result "1+2+...+num>".
#Author: Alfred Zhao
#Creation: 2015-05-07
#Version: 1.0.0
i=0 #i
s=0 #sum
echo -e "This program will help you calculate the result of '1+2+...+num'n>"
read -p "Please input your num: >" num
if [ "$(echo >"$num"|grep '[0-9]'|grep -v '[:alpha:]')>" == ">" ]; then
echo -e "Waring: Please input a number.n>"
exit 1
elif [ "$num>" -lt "1>" ]; then
echo -e "Waring: Not support.n>"
elif [ "$num>" == "1>" ]; then
echo -e "1=1n>"
exit 0
elif [ "$num>" == "2>" ]; then
echo -e "1+2=3n>"
exit 0
elif [ "$num>" == "3>" ]; then
echo -e "1+2+3=6n>"
exit 0
else
while [ "$i>" != "$num>" ]
do
i=$(($i+1))
s=$(($s+$i))
done
echo -e "n1+2+...+$num= $sn>"
exit 0
fi
for do done(固定循环)
for do done 第一种用法示例:
练习7:循环输出变量who的内容
#!/bin/bash
#Usage: for do done
#Author: Alfred Zhao
#Creation: 2015-05-07
#Version: 1.0.0
for who in mum dad brother sister
do
echo -e "This is my ${who}.n>"
done
for do done 第二种用法示例:
练习8:计算1+2+..+100的值
#!/bin/bash
#Usage: 1+2+...+100
#Author: Alfred Zhao
#Creation: 2015-05-07
#Version: 1.0.0
sum=0
for ((i=1; i<=100; i=i+1))
do
sum=$(($sum+$i))
done
echo -e "The result is $sum.n>"
如果数据库里有上百个DATABASE LINK, 而且同时要管理几十套这样的数据库,在日后改数据库用户密码时就要格外注意是否有DB LINK在使用,否则只改了LOCAL DB 的用户密码,没有级连修改REMOTE DB 的Database Link 密码,造成访问DB LINK时出错,现在去统计所有DB Link 是件很费时间的事。
自己整理了个简单的SHELL 去收集LOCAL 的所有DB LINKS,功能是如果DB LINK创建使用的是简单方式(没有配置TNSNAMES.ORA)直接取IP:PORT, 或如果使用TNSNAME Alias Name调用TNSPING 转换成IP, 同时还会判断tnsping ip port 里否通?
— I hope it’s useful
#
# file : dl.sh
# author: weejar (anbob.com)
# desc: tend to collect all DB links
# call: sh dl.sh
# date: 2015-5-5
# hp-ux , aix have tested.
# version: 0.2
# 0.1 to tnsping ip
# 0.2 to add isvalid flag
. ~/.profile
# temp file of db_link list
FILE_DBLINK=dl`hostname`_`date +%Y%m%d`.txt
# the result file
FILE_DBLINK1=2.txt
sqlplus -s / as sysdba << ! |sed '/^$/d' > $FILE_DBLINK
set timing off time off
set feed off
set lines 200 pages 1000
col owner for a20
col db_link for a40
col HOST for a20
col created for a10
set heading off
SELECT owner,
db_link,
username,
CASE
WHEN INSTR (UPPER (HOST), 'DESCRIPTION') > 1
THEN
REGEXP_SUBSTR (
UPPER (
REGEXP_SUBSTR (
UPPER (HOST),
'HOST[^=]*=[^0-9]*[0-9]+.[0-9]+.[0-9]+.[0-9]+')),
'[0-9]+.[0-9]+.[0-9]+.[0-9]+')
||':'|| REGEXP_SUBSTR (
UPPER (
REGEXP_SUBSTR (UPPER (HOST), 'PORT[^=]*=[^0-9]*[0-9]+')),
'[0-9]+')
ELSE
host
END as host
,TO_CHAR (created, 'yyyymmdd') created
FROM dba_db_links;
!
while read line
do
# TNS=`echo "$line>"|awk '$4 !~ /:/ && NF==5 {print $4}'`
TNS=`echo "$line>"|awk 'NF==5 {print $4}'`
echo "to convert tnsnames alias $TNS to IP...>"
# linux
# IPS=`tnsping $TNS|grep "DESCRIPT>"|grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}'|tr "\n>" ",>"`
# HP unix
TNSTR=`tnsping $TNS|tail -n 2`
IPS=`echo $TNSTR|grep "DESCRIPT>"|sed -e 's/.*HOST *= *//' -e 's/ *).*//'|tr "\n>" ",>"`
ISOK=`echo $TNSTR|tail -n 1|grep "OK>"|wc -l`
if [ -z "$IPS>" ]; then
IPS=N/A
fi
if [ 1 -eq "$ISOK>" ]; then
# awk '{if ($1 ~ /^all/) print $0, "anotherthing>"; else print $0}'
# linux
# sed -i "/$line/ s/$/t valid/>" $FILE_DBLINK
ISVALID=YES
else
ISVALID=N/A
fi
echo "$line t $IPS t $ISVALID>" >>$FILE_DBLINK1
done < $FILE_DBLINK
echo "RESULT FILE NAME: $FILE_DBLINK1>"
echo "================== if had errors to contact weejar@gmail.com ========================>"
echo "done.>"
# Alias
alias ga='git add .'
alias gam='git add -A && git commit'
alias gamm='git add -A && git commit -m'
autoPush() {
git add -A
git commit -m $1
git push
}
alias g=autoPush
alias gp='git push && git push --tags'
alias gs='git status '
alias gf='git fetch '
alias gm='git merge '
alias gmm='git merge origin/master'
alias dc="cd /Users/apple/Desktop>"
alias ..='cd ..'
alias ...='cd ../..'
alias ....=' cd ../../..'
alias vim='/Applications/MacVim.app/Contents/MacOS/Vim '
alias v='vim'
alias v.='vim .'
这些重命名能够对于我来说用起来还是很爽的. 每次输入 g “Commit>”, 然后就会自动完成 git addgit commitgit push三个命令.
最近玩弄 Jenkins 较多,构建服务器基本是 Mac OS 和 Linux,虽说有许多现成插件可用,但不敢不说 Execute Shell这个东西都是即开即用,方便而灵活的。因此不断的要和 Shell 打交道,真正通用的的 Shell 自然是 Bash,在 Mac OS 下可发现自带了 zsh, ksh 和 tcsh,考虑到 Linux 还是 Bash 吧。
case String in
pattern1)
statement
;;
pattern2 | pattern3)
;;
statement
*)
statement
;;
esac
要说这个语法还有些怪异,模式后只用单右括号,;; 相当于是 break, 结尾是 case 反着写的的 esac
不举例子,看何时真正用上再细究。
2. 循环语句
最常用的 for 基本语法是
for variable in sequence
do
statement
done
也可以像前面 if 那样的写法,把 do 提到上一行去
for variable in sequence; do
statement
done
这是代码风格问题,for 和 do 两个命令写成一行就需要用分号隔开。来看可以怎么产生需要的序列
for 的参数 hello 和 world
bash-3.2$ for k in hello world
> do
> echo $k
> done
hello
world
seq 命令产生序列号
bash-3.2$ for k in $(seq 1 3); do echo "number: $k>"; done
number: 1
number: 2
number: 3
其他命令的输出行
for k in `ls`; do echo $k; done
#或
for k in $(ls); do echo $k; done
那么这里不得不提到 C-Style 的循环
bash-3.2$ for ((i= 0; i < 5; i++ )); do echo "Welcome $i time.>"; done
Welcome 0 time.
Welcome 1 time.
Welcome 2 time.
Welcome 3 time.
Welcome 4 time.
我们也要注意到这里 for 后面 ((…)) 中的写法也不像 [ … ] 里那么严格,(( 后可以不用空格,等号前后可以不用空格,就是按照 C 的写法,只是必须双重括号。
还能定义并遍历数组
#!/bin/bash
# define an array called fruits
fruits=("Apple>" "Mango>" "Pineapple>" "Banana>" "Orange>" "Papaya>" "Watermelon>")
len=${#fruits[*]} # get total elements in an array,or ${#fruit[@]}
# print it
for (( i=0; i<${len}; i++ ));
do
echo "${fruits[$i]}>"
done
-a Each name is an indexed array variable (see Arrays above).
-A Each name is an associative array variable (see Arrays above). #没有这个说明bash的版本在4.0一下
关联数组的操作语法和数组的操作语法完全一致,如下常见的操作。
语法 描述
${!array[*]} 取关联数组所有键
${!array[@]} 取关联数组所有键
${array[*]} 取关联数组所有值
${array[@]} 取关联数组所有值
${#array[*]} 关联数组的长度
${#array[@]} 关联数组的长度
运行一下代码如果bash版本低于bash 4.0会有错误提示。升级后才能这样写。
#!/bin/bash
declare -A beatles
beatles=( [singer]=John [bassist]=Paul [drummer]=Ringo [guitarist]=George )
for musician in singer bassist drummer guitarist
do
echo "The ${musician} is ${beatles[$musician]}.>"
done
wget http://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz
tar zxvf bash-4.3.tar.gz
cd bash-4.3
./configure
make
make install
mv /bin/bash /bin/bash.bak; ln -s /usr/local/bin/bash /bin/bash
# !/bin/sh
echo "shell function operation>"
func1()
{
local num1 =100
local num2 =100
let sum =$num1 +$num2
return $sum
}
func2()
{
local num1 =100
local num2 =155
let sum =$num1 +$num2
return $sum
}
func3()
{
local num1 =100
local num2 =156
let sum =$num1 +$num2
return $sum
}
func4()
{
local num1 =100
local num2 =156
let sum =$num1 +$num2
echo $sum
}
func1
echo "called func1:$?>"
func2
echo "called func2:$?>"
func3
echo "called func3:$?>"
sum =`func4`
echo "called func4:$sum >"
在 Mac OS X 上,我们可以在 Users & Groups设置中指定 Network Account Server来开启网络账户的登录。但是,当我试图讲网络账户的默认 shell 从 bash 修改为 zsh 的时候,出现了问题。
直接执行 chsh命令,会在默认编辑器中打开下面的内容:
# Changing user information for rzeng.
# Use "passwd>" to change the password.
##
# Open Directory: /Active Directory/XXXX/xxxx.com
##
Shell: /bin/bash
Full Name: Rong Zeng
Office Location:
Office Phone:
Home Phone:
当编辑了 shell:的值之后,保存会出现这样的提示:
chsh: Operation was denied because the current credentials do not have the appropriate privileges. Operation was denied because the current credentials do not have the appropriate privileges.chsh: no changes made