SHELL小总结

Where there is a shell, there is a way.

SHELL Scripts Programming

bash (CentOS)

shell?

where is shell?

常见的shell种类

cat /etc/shells
chsh -l
ls /bin/*sh 
ls /sbin/nologin
rpm -ivh tcsh ksh

4. shell环境的切换

临时切换:
ps u #ps aux
pstree | grep "sh"
ksh
csh

echo $SHLVL #shell的层数

chsh
usermod -s /sbin/nologin tom

bash的常用快捷键

tab
两次tab
ctrl + i
ctrl + a
ctrl + e
ctrl + f
ctrl + b
ctrl + k
ctrl + u
ctrl + l
ctrl + p
alt  + . 上一条命令的最后一个参数

6. 命令历史

vim /etc/profile
HISTSIZE=5, history的结果就只有最近的5条了, 退出时, 自动将这5条覆盖写入~/.bash_history, 
. /etc/profile #将/etc/profile看成一个脚本文件
登录时, 读~/.bash_history, 文件中命令数目也被截为HISTFILESIZE的值.  
set | grep HISTSIZE
!10
!f #最近执行过fdisk -l /dev/sda
!! #上一条

shell脚本中的特殊字符

""
''

\ 单字符转义
"" 弱字符串转义($ !不可以)
'' 强字符串转义

echo \*

echo  "* *"
echo "$USER"
echo "!!"
换成单引号

`` #echo "aa $LOGNAME, `date +%T` bb cc"
;
&
() 创建成组的命令, 在子shell中运行, a=( $( ls ) ), 注意a会成为数组
{} 组合 touch a{1,2,3,4}
  创建命令块, 或叫匿名函数
|
Linux 默认提供了三个I/O 通道
Standard Input, 文件描述符: 0, 默认是键盘
Standard Output, 文件描述符: 1, 默认是终端显示器
Standard Error, 文件描述符: 2, 默认是终端显示器
几条命令:
cut -d: -f1 /etc/passwd | sort -r | less
ls -l | mail -s 'file list' tom@gmail.com
cat files_to_delete.txt | xargs rm -f #将输入转化为参数列表
ls *.sh | xargs rm -f

env | tee env.out

< #tr 'a-z' 'A-Z' < file1
>
* ? [] ^ 模式匹配 #[]有且仅有1个 ?也是有且仅有1个
!
$ 取变量的值
#
空格, 制表符, 换行符 当做空白

#########

特殊符号:
${var1}
`` $(cmd) 命令替换
( cmd1; cmd2 ) &> /dev/null 子shell中执行命令, 注意可以取得当前父shell的本地变量
{ cmd1; cmd2; } &> /dev/null 当前shell中执行命令

a=$(( 10 + 20 )) 数学运算(POSIX标准的扩展)
a=$[ 10 + 20 ] 数学运算
(( a = 10 + 20 ))

(())复合命令, 做整数算术运算或算术比较, (( a=10*2 )), (( 10-10 )), (( 10>5 )), (( 10>20 )), 查看$?的值, 算出值非0则$?返回0
(( a += 1 ))
(( a=b % c ))

推荐作法: 整数数值的比较、运算均用(())
while (( a < b )); do
done
if (( a == 0 )); then
fi
for (( i=1; i<=5; i++ )); do
done

推荐作法: 字符串的比较用[[]]
if [[ $a = true ]]

[] 必选其中一个 grep "ro[opq]t"
  测试: if [ 5 -gt 4 ]
  if [[ "abc" == "def" ]]
() 数组 (0 1 2 3 4)
&& 
|| 

#########

shell的特性

命令别名
ls -lth #t 按修改时间排序, ls -l即修改时间
alias
unalias
别名 函数 内部命令 外部命令

#shell不需要启动一个单独的进程来运行内部命令
#shell需要创建(fork)和执行(exec)一个新的子进程来运行外部命令

#########
命令替换
userNum=`w | grep "tty" | wc -l`
rpm -qf `which fdisk`
rm -rf `find / -user tom`
pkg=$(rpm -qf $(which fdisk)) #里面的$()也可换成``
#########

#########
|与重定向
ls > file1 2>&1
ls &> file1
ls &>> file1 #bash4.0或以上支持
grep "tom" /etc/passwd &> /dev/null
cat > /etc/yum.repos.d/rhel.repo << EOF
abc
def
EOF

shell的输入输出控制

echo -n "abc"
echo -e "abc\t\tabc"

#########
a=abc
b=def
a=$a'\n'$b
echo $a
echo -e $a
#########

name='tom'
printf 'name is %s\n' $name

读取用户输入: read

read var1
read var1 var2 var3
read -p "please input a num: " var1

read -s pwd #不显示出来

 变量分类

本地变量(用户自定义变量)
var1=ds
var1="ds tech"
var1='ds tech'
var2="cs $var1 cs"
var2='cs $var1 cs'
echo $var1
echo ${var1}23

---------------------------------------------------------------
echo ${var1:+$var2}
echo $var1 $var2

echo ${var1:-$var2}
echo $var1 $var2

echo ${var1:?$var2}
echo $var1 $var2

echo ${var1:=$var2}
echo $var1 $var2
---------------------------------------------------------------
var1=abcdefghij
echo ${var1:3:2}
echo ${var1:3}
echo ${#var1}

expr length $var1
expr substr $var1 3 2
expr substr $var1 3 99

declare -i sum=10+20+30
readonly
declare -r sum
set
unset var1
#########
环境变量
var1=colin.com
export var1
export var1=colin.com

declare -x sum
export | grep "sum"
env
printenv

PATH #仅对外部命令
HOME
UID
HOSTNAME
PWD
#########
位置参数变量
$0 $1 ... ${10}
service#$0 network#$1 restart#$2

#########
关于循环获取位置参数变量:

$1 $2 $3 ...
1 增长到2 3 ...
i=1 i++
$$i, 这样是不行的, shell不支持变量名是变量,

方法1: shift
使用shift, 执行一次shift, 位置参数往左移一个, 原先的$2变成了$1,
只要获取$1即可获取后面的$2 $3 ...的值
while (( $# > 0 ))
do
echo $1;
shift;
done
exit 0;
方法2: 使用$@
for i in "$@"
do
echo "$i";
done
exit 0;
方法3: 间接引用
i=1;
while (( i <= $# ))
do
echo ${!i};
let i++; #(( i++ ))
done
exit 0;

#########
预定义变量(特殊变量)
$#
$$ #本shell的PID值, 当前进程ID号

$@ $*
"$*"以"$1 $2..."的形式保存所有输入的命令行参数
"$@"以"$1" "$2"...的形式
for i in "$*" 或 "$@"
do
echo $i;
done

$? #[0, 255]整数
每个命令在退出时都会返回一个退出状态值(exit status)
正常退出, 返回0
异常退出, 返回非0
退出状态值保存在特殊变量$? 中

算术运算

仅整数

bash只支持整数的运算, 浮点数运算可以使用bc
echo "scale=3; 13/2" | bc #scale为小数点位数

declare -i a
a=5+5

a=1+2
echo $a
echo 1+2

expr 1 \* 2
USAGE=$( expr $USED \* 100 / $TOTAL )

echo $[ 10 * 20 ]
echo $(( 3**(1+1+1) )) #()用来改变运算顺序
(( a=10 * 20 )) #(())主要用来数学计算

let a=5+9 #let常用来赋值
let b=$a-3 c=$a*2 c=$a/3 d=$a%3
declare -i a=3**3

a=3
let b=$a**3

let a++
let a+=10
#########
浮点数运算
rpm -q bc
bc
echo "3.14*2" | bc

echo "scale=3; 10/3" | bc #3位小数

数组

在白板上画出数组图, 0号元素, 1号元素, 2号元素
目前只支持一维数组
索引数组
names[0]=colin
names[1]=jerry
names[2]=lee
names[3]=kevin

遍历数组:
for i in ${names[@]}
do
echo $i;
done

#########
names[x++]=colin
names[x++]=jerry
names[x++]=lee
names[x++]=kevin
用在循环中就很好的生成了数组, 或将一些值逐一放入数组中如: 
for i in tom jerry lee mike
do
names[x++]=$i;
done
for i in ${names[@]}
do
echo $i;
done
-----------------------------------------------------
r=( `route -n | grep "UG"` ) #r变成了数组
echo ${r[3]}

var1="aa bb cc"
var2=( $var1 ) #var2变成了数组
echo ${var2[1]}

#########
echo ${names[0]}

names=(colin jerry lee kevin)
names=([0]=colin [1]=jerry [3]=lee [5]=kevin cali)
names=(tom [5]=jerry lee)

echo ${names[@]}
echo ${names[*]}

echo ${#names[@]}
echo ${#names[*]}
echo ${!names[@]} #打印下标值
echo ${!names[*]}

echo ${names[2]}
echo ${#names[2]}

unset names
unset names[2]

#########
关联数组
bash 4.0版本开始支持关联数组
declare -A a
a=([userName]=tom [pwd]=password1 [age]=20 [addr]=hncs)
a[gender]=male

bash的启动配置文件(环境变量配置文件)

登录shell
login shell 指的是输入用户名、密码, 从系统登录时执行的第一个程序

/etc/profile

/etc/profile.d/*.sh

~/.bash_profile

~/.bashrc

/etc/bashrc

非登录shell
登录系统后, 在login shell里启动的shell是非login shell
如执行bash命令、在图形中打开终端均是开一个非登录shell
login shell与non login shell在启动时执行不同的初始化脚本

/etc/profile.d/*.sh
~/.bashrc
/etc/bashrc

su例子:
su tom #非登录shell, 执行哪些文件?
su - tom #登录shell, 执行哪些文件?

退出登录shell时, 执行~/.bash_logout

执行shell脚本的方法

chmod +x test.sh
./test.sh #在子shell中执行, 一般用这种方法

bash test.sh #在子shell

source test.sh #. test.sh, 在当前shell
echo $a #a是在test.sh中定义的一个变量

运行多个命令

cd /tmp; ls

在子shell中运行命令

( cd /tmp; ls )

命令的返回值$?

有条件地运行多个命令(列表)
ls file1 &> /dev/null && cat file1

bash的只读变量
$?
$$ 当前shell的PID
$_ 前一个命令的最后参数
$PPID shell父进程的PID
UID

bash预赋值的变量

BASH_VERSION
OLDPWD
RANDOM

{}替换
mkdir chap{01,02,03,04}
mkdir -p chap{01,02,03,04}/{html,text}
touch file{1..10}

一条find命令
find /etc -name *.conf
touch a.conf b.conf
find /etc -name *.conf
find /etc -name "*.conf" #用""引起来

bash shell的基本语法

条件测试
任何命令都可以作为条件, 执行并检查命令的返回值

#########

if [ ! -d "/tmp/{sda1,sda3}" ]
then
( mkdir /tmp/{sda1,sda3} > /dev/null 2>&1 )
fi

#########

if ls $1
then
chmod 600 $1;
else
echo "the file $1 does not exist";
fi;
#########

if test -e $1
if [ -e $1 ]

#########
对命令执行结果的判断:
if rpm -q gcc
then 
echo yes; 
else 
echo no; 
fi

rpm -q gcc && echo 'ok' || echo 'please install gcc !';

测试文件状态:
test -r "$file1" -a -s "$file1"
[ -f file1 ]

[ -d /etc/vsftpd ]
echo $?

[ -e /mnt/Server ] && echo 'yes' || echo 'no';

整数值比较:
中间可用逻辑运算符: -a -o !
    [  $a -gt $b -a $b -gt $c ]  && echo 'a is largest'
[ `who | wc -l` -le 10 ] && echo 'ok'

var1=`df -hT | grep "/boot" | awk '{print $6}' | cut -d "%" -f 1`
[ $var1 -gt 90 ] && echo 'ok'

if (( a > b && b > c ))
then
echo 'a is largest';
fi

字符串比较:
=或== 两个字符串相等
!= 两个字符串不等
-z 空字符串
-n 非空字符串

    [[]]主要用来字符串比较
if [[ $location =~ "-" || $location =~ "^:" ]] #包含有-, 或以:开头, ":$", 以:结尾

    
[[ "$a" == "abc" ]] #字符串比较一般用[[]], 变量$a用""括起来, 防止$a的值中有空格

read -p  "input: " file
[[ "$file" = "/etc/fstab" ]] && echo "ok";

[[ $LANG != "en.US" ]] && echo $LANG

[[ -z `cat file1` ]] && echo "ok";

逻辑测试(逻辑判断)(列表)
[[ "$USER" = "tom" ]] || echo "not tom";

[ -f /etc/file1 -o -f /etc/file2 ] && echo "ok"

[ ! -x /etc/file1 ] && echo "no exec"

[[ $USER == "root" && $SHELL = "/bin/bash" ]] && echo "ok"

#########
if

if 命令
then
...
fi

若一条命令成功执行了, 就做什么, 没成功, 就做什么,
3种做法:
1.
if ls -d /dir1
then
echo "ok";
else
echo "fail";
fi
---------
2.
ls -d /dir
if (( $? == 0 )) #[ $? -eq 0 ]
then
echo "ok";
else
echo "fail";
fi
---------
3. 列表
ls -d /dir && echo ok || echo fail;

#########
if ping -c3 server1
then
echo 'server1 is up';
fi
#########

echo -n "how old are you"
read age
if (( age <= 0 || age >= 120 ))
then
echo "error"
exit 1;
fi
#########
if [ -r $file -a -w $file -a -x $file ]
#########
a=0;
if test $a -eq 1
then
echo "yes";
else
echo "no";
fi;
#########
a="abcdefg";
if echo $a | grep "abc"
then
echo yes;
else
echo no;
fi;
#########
file1="/var/log/messages"
if [ -f $file1 ]
then
wc -l $file1
fi
#########
read -p "input: " dir1
if [ -d $dir1 ] 
then
echo "$dir1 exist";
else
echo "$dir1 not exist";
mkidr $dir1;
fi 
#########
uNum=`who | wc -l`
if (( uNum > 3 )) #[ $uNum -gt 3 ]
then
echo "$uNum";
else
echo "...";
who | awk '{print $1,$2}'
fi
#########
pgrep "vsftpd" &> /dev/null
if [ $? -eq 0 ]
then
echo ...;
elif [ -x "/etc/init.d/vsftpd" ]
then
service vsftpd start
else
echo "no";
fi;
#########
service mysqld status &> /dev/null;
if [ $? -ne 0 ]
then
echo "at time: `date` mysql is down" >> /var/log/messages;
service mysqld restart;
fi

#########
for语句:
for day in "Monday" "Wednesday" "Friday"
do
echo $day;
done
#########
for i in `cat iplist`
do
echo $i;
done | tee file1
mail -s "WRONG!" u1@ds.com,u2@ds.com < file1
#########
for file in /boot/*
do
echo "$file"; #basename "$file";
done
#########
for i in `find | grep "xml$" | grep "^comps"`
do
  createrepo -g ${i} Server/
done
#########

for file in "$@" #简写为for file
do
if [ -e $file ]
...
done

for i in "$@"
for i in /etc/*.conf
for i in $(command)

#########

for dir in "$@"
do
if [ -d $dir ]
then
if [ "$dir" == "." -o "$dir" == ".." ] #[[ "$dir" == "." || "$dir" = ".." ]]
then
echo "skipping ..."
else
basename $dir

tar czf $dir.tgz $dir && rm -rf $dir
fi
else
echo "skipping non directory $dir";
fi
done
#########
dir1="/opt/*"
lmt=20
u=`grep "/bin/bash" /etc/passwd | cut -d ":" -f 1`
for user in $u
do
num=`find $dir1 -user $user | wc -l`
if [ $num -gt $lmt ]
then
echo "$user have $num files"
fi
done
#########
for i in `seq 1 9` #seq 9
for i in $( ls )
for i in /opt/*

#########

result=0;
while [ $# -gt 0 ]
do
result=`expr $result + $1`;
shift;
done
echo "the sum is: $result";

#########
for i in $* #$@也可, 或简写成for i也可
do
echo $1;
shift;
done
#########
for i in `seq 1 6` #{1..6} 或seq 6
do
if (( $i % 2 == 0 ))
then
break; #continue break与continue的使用
fi
echo $i;
done
echo "over";

#########

for (( i=0; i<=3; i++ ))
do
echo;
for (( j=0; j<=5; j++))
do
echo -n "$i, $j";
[ $j == 3 ] && break #continue;
done
done

#########

while :
do
read -p "input a string: " str
echo $str >> /tmp/input.txt
if [[ "$str" == "END" ]]; then
break;
fi
done
wc /tmp/input.txt
rm -f /tmp/input.txt

#########
i=1
while (( i <= 20 )) #[ $i -le 20 ]
do
if [ $i -eq 8 ] || [ $i -eq 18 ]; then
let i++;
continue;
fi
userdel -r stu$i
let i++;
done

#########

size=$( ls -l $( find /etc -type f -a -name "*.conf" ) | awk '{print $5}' )
#find /etc -type f -name "*.conf" | xargs ls -l | awk '{print $5}'
total=0
for i in $size
do
total=`expr $total + $i` #let total+=i (( total+=i ))
done
echo "total size is $total"

#########

counter=0
for i in 1 2 3 4 5
do
(( counter++ ))
(( counter+=1 ))
counter=$(( $counter+1 ));
counter=$[ $counter+1 ]
counter=$( expr $counter + 1 );
let counter+=1;
let counter++;
done
echo $counter;

#########

类c风格的for
for (( i = 1; i <= 10; i++))
do
echo $i;
done

#########
while
while 命令
do
...
done

#########

while读文件内容:
vim test1.sh
while read user groups homedir 
do 
echo -e "\$user=$user\t\$groups=$groups\t\$homedir=$homedir" 
    gid=$( echo $groups | cut -d, -f1 )
    echo "\$gid=$gid" 
    sleep 2
done < file2

vim file2
tom g1,g2,g3 /home/tom
jerry g1,g2 /home/jerry
lee g1 /home/lee

#########

#!/bin/bash
PRICE=$( expr $RANDOM % 1000 ) 
#$RANDOM % 10 [0, 10)之间的随机数
#$RANDOM % 20 [0, 20)之间的随机数

TIMES=0
echo "0-999之间, 猜猜看是多少?"
while :
do
    read -p "请输入你猜测的价格数目: " INT
    let TIMES++
    if [ $INT -eq $PRICE ]
then
        echo "猜对了, 实际价格是 $PRICE"
        echo "你总共猜测了 $TIMES 次"
        exit 0
    elif [ $INT -gt $PRICE ]
then
        echo "太高了!"
    else
        echo "太低了!"
    fi
done

#########

用while 循环从文件中读取数据
while read LINE
do
echo $LINE
done < /etc/hosts

while read ip hn
do
echo "$hn --> $ip"
done < /etc/hosts

#########

a=3;
while [ $a -gt 0 ]
do
echo $a;
a=$[ $a -1 ]; #let a--;
done

#########

i=1;
while [ $i -le $# ]
do
echo ${!i} #间接变量引用, 实用
let i++;
done

#########

创建20个文件夹dir01 - dir20
fun1()
{
[ ! -d $1 ] && { mkdir $1; echo "$1 create ok"; } || echo "$1 exist";
}
a=20;
while [ $a -gt 0 ]
do
if [ $a -le 9 ]
then
b="0${a}";
fun1 dir${b};
else
fun1 dir${a};
fi
let a--;
done

#########

read -p "input: " answer
while [[ "$answer" != "ds" ]]
do
echo "error, retry";
read -p "input: " answer
done
#########
until
until 命令
do
...
done

#########

until [ -e /var/lib/mysql/mysql.sock ] 
#若/var/lib/mysql/mysql.sock文件不存在, 则说明mysqld服务未启动
do
/etc/init.d/mysqld start
done

#########

until [ -z $1 ] #$# -gt 0
do
echo "there are $# parameters: $*";
shift; #shift的使用
done

#########

a=3;
until [ $a -lt 0 ]
do
echo $a;
a=$[ $a - 1 ];
done

#########

循环监控网站的index.html, 如果访问不到页面, 则停止30秒, 继续测试
until wget -q http://192.168.10.8/index.html
do
sleep 30;
done
echo ok;
exit 0;

#########

case语句
a=0;
case $a in
[012])
echo aa;;
3|4|5)
echo bb;;
[a-z]|[A-Z])
echo cc;;
*) echo dd;;
esac

#########

select语句: 选择时选择序号
select var in 'linux' 'unix' 'macos' 'windows'
do
break;
done
echo "you select is $var";

#########

select常与case一起使用
PS3="please select: "
select var in 'linux' 'unix' 'macos' 'windows' 'quit'
do
case $var in
linux) echo "aa";;
unix)  echo "bb";;
quit)  exit 0;;
*)     echo "wrong";;
esac
done

#########

函数(function)
在Shell中, 函数就是一组命令或语句, 形成一个可用块
函数由两部分组成:
函数名(在一个脚本中必须唯一)
函数体(命令或语句集合)
#########
给函数传值, 直接接收$1、$2等, 方法与脚本接收参数是一样的, 可以用$@ $#等!
传1个就用$1, 传多个则用for i in "$@"更好!
function checkRPM()
{
for i in "$@"
do
! rpm -q $i && yum install $i -y
done
} &> /dev/null
checkRPM httpd mysql-server php gd

#########

递归调用:
#!/bin/bash
#comment
judge_ip()
{
if [[ "$1" =~ "abc" ]] #包含有abc
then
echo 'ok';
else
echo -n 'error, input: ';
read ip
judge_ip "$ip";
fi
}
judge_ip "$1"
#########
a=100
fun1()
{
echo $a;
#local b; 加与不加这行来看结果
b=200; #或local b=200
}
fun1
echo $b;
#########

引用另一个文件:
lib.sh文件 #在lib.sh中写很多公共函数
fun1()
{
date;
}

test.sh文件
#!/bin/bash
. lib.sh #在test.sh中, .一下或source一下即引用了lib.sh文件, 然后就可以用里面的函数了
fun1

#########
fun1() #先定义好, 后调用
{
if rpm -q gcc &> /dev/null
then
return 0;
else
return 1;
fi
}
if fun1
...
#########
fun1()
{
rpm -q gcc &> /dev/null;
date;
lsls;
#无显式return时, 最后一条命令的$?即是返回值
return; 
#return后没接数值, 也是最后一条命令的$?即是返回值 
}
fun1
...
#########
fun1()
{
echo "$1";
echo "$2";
}
fun1 abc xyz #fun1 $1 $2, 给函数传参数

#########

###############################################################################

expect

expect这个名字准确说明了它的作用, 即"期待"交互式程序的输出 
然后发送给该程序一些输入作为响应
expect使用Tcl, 是Tcl脚本语言的扩展
它的目的是与交互式程序进行通信

#########

在shell脚本中使用expect的方法, 一般是调用(执行)另写好的expect文件如:
#!/bin/bash
#comment
./test2.exp &> /dev/null
expect -f test2.exp &> /dev/null

#########

yum install expect

#########

vim test.exp
#!/usr/bin/expect -f
#comment
spawn passwd tom
expect "*password:*"
send "123456\r"
expect "*password:*"
send "123456\r"
expect eof

执行方法:
chmod +x test.exp
./test.exp

expect -f test.exp

#########

#!/usr/bin/expect -f
#comment
spawn yum install httpd
expect "*y/N*"
send "y\r"
expect eof

#########

#!/usr/bin/expect -f
#comment
if { $argc != 3 } { 
    puts "Usage $argv0 ..."
    exit 1 
  } 
set ip [lindex $argv 0]
set un [lindex $argv 1]
set pa [lindex $argv 2]
spawn ftp $ip
expect "*Name*"
send "$un\r"
expect "*Password:*"
send "$pa\r"
expect "*ftp>*"
send "get file1\r"
expect "*ftp>*"
send "quit\r"
expect eof

./text.exp 192.168.6.6 tom 123456 #在命令行传3个参数进去

#########

#!/usr/bin/expect -f
#comment
set ip [lindex $argv 0]
set pa [lindex $argv 1]
spawn ssh root@$ip
expect "*yes/no*" {send "yes\r"; expect "*password*" {send "$pa\r"}} \
           "*password*" {send "$pa\r"}
#expect "*abc*" {send "def\r"} "*xyz*" {send "123\r"} 若匹配abc则执行什么, 若匹配xyz则执行什么
expect eof

执行: ./test.exp 192.168.6.6 aixocm

#########

屏幕上有输出, 怎样去掉? 放入bash脚本中&> /dev/null

在bash脚本中调用expect文件:
#!/bin/bash
#comment
expect -f test2.exp &> /dev/null
./test2.exp &> /dev/null
echo $?

带颜色的输出
echo -e "\033[37;44;1mhello\033[0m world"
echo -e "\033[41mhello\033[0m world" #这样也可, 并不必要3个值, 仅设个背景色即可
echo -e "\033[31mhello\033[0m world" #这样也可, 并不必要3个值, 仅设个前景色即可

\033[引导非常规字符序列37;44;1前后顺序没有关系
m意味着设置属性然后结束非常规字符序列
hello
\033[引导非常规字符序列0设置属性到默认设置
m意味着设置属性然后结束非常规字符序列
world
前景 红31
蓝34 白37
背景 红41    蓝44白47
1表示设置粗体(无明显效果)

dialog

rpm -q dialog

每种对话框的输出或叫返回有两种:
一种: 使用退出状态码($?), "OK"为0, "Cancle"和"NO"均为1
另一种: 使用STDERR(2>)

a='abc'
b='xyz'
dialog --title "$a title" --msgbox "$b welcome" 15 50; 
dialog --title "title" --infobox "thanks" 15 50; 
sleep 3; 
dialog --clear

dialog --title "title" --yesno "are you sure" 15 50
[ $? -eq 0 ]

dialog --title "title" --inputbox "please:" 15 50 2> file1
var1=$( cat file1 )

dialog --title "title" --menu "hi, $var1" 15 50 4 \
"v1" "v11" "v2" "v22" "v3" "v33" "v4" "v44" 2> file1
var2=$( cat file1 )

dialog --title "title1" --yesno "Welcome me.\n\nAre you continue?" 15 50
#$?

---------
dialog --clear --title "title" --checklist "pick a option" 15 50 3 \ 
rh "release is redaht" on \
suse "release is suse" off \
ubutu "release is ubutu" off 2> file1
cat file1
---------

---------
dialog --clear --title "title" --nocancel --radiolist "t1\nt2\nt3\nt4" 15 50 3 \
"128" "128M memory" on \
"256" "256M memory" off \
"512" "512M memory" off 2> file1
a=`cat file1`
---------

dialog --title "copying file" --gauge "abc" 15 50;

---------
i=0;
while (( i <= 100 ))
do
echo "XXX";
echo $i;
echo "a1..."
echo "a2..."
echo "a3..."
echo "XXX";
(( i++ )) #(( i+=5 ))
sleep 0.1 #必要
done | dialog --title "title" --gauge "abc" 15 50;
---------

dialog --title "title" --form "abc" 10 30 7 
"ip:" 1 1 "" 1 5 20 0
     ip:在第几行 
"nm:" 2 1 "" 2 5 20 0
       ip:与左边线之间的距离
"gw:" 3 1 "gway" 3 5 20 0
          文本框中默认值 
"ns:" 4 1 "" 4 5 20 0
            文本框在第几行
"xx:" 5 1 "" 5 5 20 0
  文本框与左边xx:之间的距离
"yy:" 6 1 "" 6 5 20 0
文本框的宽度
"zz:" 7 1 "" 7 5 20 0
文本框中可以输入的字符的宽度(个数), 若为0则等于前面的文本框的长度20}t$" fstab

Regular Expression

正则得从编译原理里面的正规式说起了. 太酷了.

grep sed awk vim均实现了正则表达式
如 cat /etc/passwd | grep "^[A-Z]"

匹配email地址
grep -E "[a-Z0-9.]+@[a-Z0-9.]+\.[a-Z]{2,3}" file1
匹配HTTP URL
grep -E "http://[a-Z0-9.]+\.[a-Z]{2,3}" file1

正则表达式的元字符
/^love/

/love$/

/l..e/ #单个任意字符(换行符\n除外), 有且仅有一个

/abc* #ab后接0个或多个c

/o*ve #*将前面的那一个字符o重复0次或多次

/[Ll]ove #有且仅取1个

/[a-z]ove

/[A-Z]ove

/[^a-z]ove

/ove[^a-zA-Z0-9]

/love\. #love.

/\<bin\> #单词匹配, sbin不会匹配

/\(lov\)aa\1er #标签, lovaalover

:1,$ s/\([Aa]bc\)yz/\1xyz/g

:1,$ s/\(abc\) and \(xyz\)/\2 and \1/g 

/abco\{5\} #字符o连续出现5次

/abcx\{2\}y\{3\} #x重复2次, y重复3次

/abco\{5,\} #字符o连续出现至少5次

/abco\{5,10\} #字符o连续出现5到10次

/oo.* #oo后接任意字符串.*, 假如有一行以oo开头, 则这一行均匹配

以b或f或m开头的行 /^[bfm]
不是以小写字母开头的行 /^[^a-z]
/\<f.*th\>

bash提供的通配符与正则元字符的区别:
ls *.h
ls | grep "*.h"
ls | grep ".*\.h"

POSIX类字符集
/[[:digit:]] #数字
/[[:upper:]] #大写字母
grep -n "^[[:lower:]]" file1 #小写字母开头

grep的使用
global search regular expression(RE) and print out the line
Unix的grep家族包括grep、egrep和fgrep

grep "root" /etc/passwd -c #有多少行匹配
grep "root" /etc/passwd -n
grep "root" /etc/passwd /etc/shadow -h
cat /etc/grub.conf | grep -v "^#"
grep -n "^$" file1 #空白行
cat file1.sh | grep -v "^\s*$"
pstree | grep -A 2 -B 2 bash

grep支持的扩展的正则表达式元字符
grep "root|ftp" /etc/passwd -E
grep root\|ftp /etc/passwd -E

egrep "^ro{2,5}t$" fstab
egrep "^ro{2}t$" fstab
egrep "^ro{2,}t$" fstab

1. seq
seq 4 #seq 1 4, 默认从1开始, 所以可省略1
seq 3 6
seq -3 3
seq -w 10 #等宽输出, 与位数最多的对齐

2. tr
tr是单个字符处理工具, 而不是字符串处理工具
 
  替换:
1、将文件file中出现的"abc"替换为"xyz"
  cat file | tr "abc" "xyz" > new_file
  凡是在file中出现的"a"字母, 都替换成"x"字母
              "b"字母替换为"y"字母
  "c"字母替换为"z"字母
而不是将字符串"abc"替换为字符串"xyz"
 
2、使用tr命令"统一"字母大小写
cat file | tr "a-z" "A-Z" > new_file
cat file | tr "A-Z" "a-z" > new_file
 
3、把文件中的数字0-9替换为a-j
cat file | tr "0-9" "a-j" > new_file

4、制表符\011 空格符\040    
cat file | tr "\011" "\040" > new_file
 
5、冒号":"替换成换行符"\n"
  echo $PATH | tr ":" "\n"

-----------------------------------------------------------------------------------------

删除:
6、删除文件file中出现的"snail"字符
  cat file | tr -d "snail" > new_file
  凡是在file文件中出现的's','n','a','i','l'字符都会被删除, 而不是仅删除出现的"snail"字符串
 
7、删除文件file中出现的换行'\n'、制表'\t'字符
  cat file | tr -d "\n\t" > new_file
  不可见字符都得用转义字符来表示的, 这个都是统一的
 
8、删除"连续着的"重复字母, 压缩成第一个
  cat file | tr -s "a-zA-Z" > new_file
  echo "a b  c   d    e" | tr -s " " #把空格压缩成1个

9、删除空行
  cat file | tr -s "\n" > new_file
 
10、删除Windows文件"造成"的'^M'字符
  cat file | tr -d "\r" > new_file
或者
cat file | tr -s "\r" "\n" > new_file
  这里-s后面是两个参数"\r"和"\n", 用后者替换前者
 
替换或删除
echo "12M" | tr -d "M" #删掉M, 输出12, 太帅了!
tr -d " " #删掉空格

echo "12abcXYZ" | tr -d "a-zA-Z" 

echo "aaabbbccc" | tr -s "a-z" #将重复的小写字母压缩为1个, abc
echo "aaaBBB999" | tr -s "a-zA-Z0-9" #将重复的大小写字母或数字均压缩为1个, aB9
echo "a       b" | tr -s " " #将重复的的空格压缩为1个

echo "abc" | tr "a-z" "A-Z" #小写替换成大写

3. sort
对行进行排序, 默认字段分隔符是空白(与awk一样)
sort -t: /etc/passwd #-t指定字段分隔符
sort -t: -k3 /etc/passwd #-k3: 以第3个字段排序, 默认以第1个字段排序
sort -t: -k3n /etc/passwd #n表示数值
sort -t: -k3nr /etc/passwd #r表示反向

4. uniq
先sort再uniq:
111
111
222
111

去掉重复行
vim file1
111
111
111
222
222
333
---------
uniq -u file1 #只打印唯一的行
---------
uniq -c file1 #将每行重复出现的次数打印在行首
3 111
2 222
1 333

5. cut
默认字段分隔符为tab, 不是空白, 所以不好控制
cut -d " " -f 2 #指定字段分隔符为1个空格, 打印第2列 

6. sed
\s任意的空白符, 包括空格、制表符(tab)、换行符、中文全角空格 
\s空白字符: [ \t\n\x0B\f\r]
\t 制表符(tab) ('\u0009')  
\n 新行, 换行符 ('\u000A')  
\r 回车符 ('\u000D')  
\f 换页符 ('\u000C')  
\a 报警 (bell) 符 ('\u0007')  
\e 转义符 ('\u001B')  
\cx 对应于x的控制符  

sed -i '/^\s*security = user/s/user/share/' smb.conf
sed -n '/^\s*security = user/p' smb.conf
sed -i 's/^\s*security =.*/\tsecurity = share/' smb.conf
sed -i 's/.*hosts allow.*/\thosts allow = 127. 192.168.0.0\/16/' smb.conf
sed -i '/hosts allow/s/^.*$/\thosts allow = 127. 192.168.0.0\/16/' smb.conf

stream editor, 完美地配合正则使用, 主要进行文本替换 
sed [options] 'command' file[s]
定位(址)
sed -n '1p' file1
sed -n '$p' file1 #最后一行
sed '2,4p' file1
sed -n '2,4p' file1
sed -n '2,+4p' file1
sed -n '1p;4p;7p' file1 #只打印第1 4 7这3行
sed '1s/abc/YYY/; 4s/abc/YYY/' file1

sed支持的基本正则
sed -n '/^root/p' file1
sed -n '/^[^0-9]/p' file1
sed -n '/r..t/p' file1

sed支持的扩展正则
sed -rn '/roo?t/p' file1 #扩展正则, o?, 0个或1个
sed -rn '/roo+t/p' file1 #扩展正则, o+, 1个或多个
grep -E "[a-Z0-9.]+@[a-Z0-9.]+\.[a-Z]{2,3}" file1

sed函数的使用
a
i
c
d 删除
r
w

sed '/localhost/a ds.com ftp' file1 #a, 先匹配localhost, 然后在其后插入新行 ds.com ftp
sed '/localhost/r /etc/file2' file1 #r, 读取另一文件的内容
sed '4r file2' file1
sed -n '/aixocm/w file2' file1 #w另存为, file2的内容被覆盖
sed '/root/c aixocm' file1 #先匹配root, 将整个这一行替换成aixocm
sed '/127/d' file1
sed '/tom/d' file1
sed '/tom/!d' file1
sed '3d' file1
sed '1,3d' file1
sed '3,$d' file1
sed '$a AAA=XYZ' file1 #在file1末行后加一行AAA=XYZ
cat file1 | sed '/^$/d'
sed -e '1,3d' -e 's/word1/word2/g' file1

引用变量
var="root"
sed "/$var/c aixocm" file1 #换成""即可

text="hello"
echo "hello world" | sed "s/$text/HELLO/"

另一种替换:
sed 's/root/ROOT/' file1
sed 's/root/ROOT/g' file1
sed 's/root/ROOT/2' file1
sed '/word1/s/word2/word3/g' file1
cat file1 | sed 's/pattern/replace_string/' #从stdin中读取输入

sed 's/text/replace/' file1 > newfile
mv newfile file1

sed -i 's/text/replace/' file1

echo "this thisthisthis" | sed 's/this/THIS/'
echo "this thisthisthis" | sed 's/this/THIS/g'
echo "this thisthisthis" | sed 's/this/THIS/3g'

echo "a b c" | sed 's/ //g'

/在sed中作为定界符, 可使用任意的定界符如:
sed 's:text:replace:' file1 #不推荐

echo "ab/c def" | sed 's/ab\/c/xxx/' #要将/转义\/

sed '/^$/d' file1 #直接回车产生的空白行
sed '/^\s*$/d' file1 #若这行中有空格或tab, \s表示空白

echo "this is an example" | sed -r 's/\w+/[&]/g' #匹配一个单词
echo "this is an example" | sed -r 's/[a-Z]+/[&]/g' #匹配一个单词 

若用了-n, 就要用p, 不然没有显示

sed '1,$ s/root/ROOT/g' file1 #1,$不要也可, 默认即所有行
sed '2 s/root/ROOT/g' file1 #只替换第2行的root->ROOT
sed -i '2,4 s/.*/abcdefg/' file1 #用abcdefg替换file1中2到4行

去行首#
sed '/ADDR/s/^#//' file1

行首加#
sed '/ADDR/s/^/#/' file1
ls -l | sed 's/^/ /'
ls -l | sed 's/^/\t/'

多次替换
sed 's/localhost/WWW/' file1 | sed 's/127/001/'
sed -e 's/localhost/www/' -e 's/127/001/' file1
sed 's/localhost/www/; s/127/001/' file1 #组合多个表达式

sed标签(子串匹配), 第1个子串\1, 第2个子串\2
sed 's/\(root\)/\1_aixocm/g' file1
sed -r 's/(root)/\1_aixocm/g' file1
sed -r 's/(root)/&_aixocm/g' file1

echo "this is digit 7 in a number" | sed -r 's/digit ([0-9])/\1/'
echo "seven eight" | sed 's/([a-Z]+)([a-Z]+)/\2 \1/'

范围匹配
sed '/abc/,/xyz/s/aixocm/YYY/' file1 #将abc与xyz之间的aixocm -> YYY, 其它地方的aixocm不会
sed '/abc/,/xyz/s/aixocm.*/YYY/' file1
sed '/abc/,/xyz/s/.*aixocm/YYY/' file1
sed '/abc/,/xyz/s/.*aixocm.*/YYY/' file1 #包含有aixocm的整行被替换

sed -n '/abc/,/xyz/p' file1

sed改配置文件:
sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/sysconfig/selinux
sed -i '/UseDNS/s/^.*$/UseDNS no/' /etc/ssh/sshd_config

sed -n '/ext4/p' /etc/fstab
sed '/ext4/d' /etc/fstab
sed '/^#/d' file1
sed -e 's/old/new/g' -e 's/[0-9]$/&.yyy/' file1

7. awk
是gawk的符号链接, 3位作者的名字的首字母(man awk), 是一门编程语言, 灵活性是awk最大的优势
awk 'BEGIN{commands}pattern {commands}END{commands}' file1
BEGIN语句块可选, pattern语句块可选, {}语句块可选, END语句块可选

就像一个用来读取行的while循环, 从第一行读至最后一行, 
每读一行, 先检查该行与pattern是否匹配, 若匹配, 则执行{}中的语句, 
然后再读取下一行

工作原理:
1. 执行BEGIN{commands}语句块中的语句
2. 从文件或stdin中读取第1行, 然后执行pattern {commands}, 重复这个过程, 直到所有行被读取完毕
3. 执行END{commands}语句块中的语句

默认以空白作为字段分隔符
基本结构:
awk 'BEGIN{commands}pattern {commands}END{commands}' file1
awk 'BEGIN{print "start..."}{print $1}END{print "end..."}' file1
awk 'BEGIN{i=0}{i++}END{print i}' file1 #文件总行数, 改为""双引号也可

awk的基本介绍
与sed一样, 均是一行一行的读取、处理, sed作用于一整行的处理, 而awk将一行分成数个字段来处理
默认的字段分隔符为空白

vim file1
abc def:hij:123:456:xyz:789
awk -F "[ :]" '{print $1, $2}' file1
输出abc def
字段分隔符是正则, 用""引起正则[ :], 防止shell将它解释成shell的元字符
以空格或:作为字段分隔符, 空格与:一样均为分隔符(:就是空格!)

tom  savege  100
molly  lee  20
john  doe  300
awk '{print $1, $3}' file1
head -l /etc/passwd | cut -d ":" -f 1-3 #与cut对比一下 -f 1,3,5
取网关、IP地址

ifconfig -a | grep "^\w" | awk '!/lo/{print $1}'

echo | awk '{var1="abc"; var2="ijk"; var3=100; print var1, var2, var3}'
echo | awk '{var1="abc"; var2="ijk"; var3=100; print var1 var2 var3}'
echo | awk '{var1="abc"; var2="ijk"; var3=100; print var1 "---" var2 "---" var3}'

awk -F: '{print NR, NF, $1, $NF, $(NF-1)}' /etc/passwd

awk -F ":" '{print $1, "lines=" NR, "columns=" NF}' /etc/passwd

awk -F: 'NR==2{print $1}' /etc/passwd

统计文件的行数:
awk 'END{print NR}' file1

seq 5 | awk 'BEGIN{sum=0; print "sum:"}{print $1"+"; sum+=$1}END{print "="; print sum}'
seq 5 | awk '{sum+=$1}END{print sum}'

将外部变量传给awk:
var=100
echo | awk -v v1=$var '{print v1}'

var1=10; var2=20
echo | awk '{print v1, v2}' v1=$var1 v2=$var2 #输入来自stdin
awk '{print v1, v2}' v1=$var1 v2=$var2 file1 #输入来自file

行过滤:
awk -F: 'NR==2{print $1}' /etc/passwd
awk -F: 'NR==2,NR==4{print $1}' /etc/passwd #2至4行
awk -F: 'NR==2 || NR==4{print $1}' /etc/passwd #第2行和第4行
awk -F: 'NR<5{print $1}' /etc/passwd
awk -F: 'NR<=5{print $1}' /etc/passwd

整行与正则匹配
awk -F: '/root/{print $1}' /etc/passwd
awk -F: '/^root/{print $1}' /etc/passwd
awk -F: '!/root/{print $1}' /etc/passwd
awk -F: '$0 ~ /root/{print $1}' /etc/passwd #相当于这样

另一种写法: 打印匹配行
awk '/root/' /etc/passwd
awk '/^root/' /etc/passwd

字段与正则匹配
awk -F: '$7 !~ /bash/{print $1}' /etc/passwd #~匹配 !~不匹配

设置字段定界符:
awk -F: '{print $1}' /etc/passwd
awk 'BEGIN{FS=":"; OFS="---"}{print $1, $NF}' /etc/passwd

awk -F: 'OFS="---"{print $1, $3}' /etc/passwd

awk -F: 'BEGIN{OFS="---"}NR==2{print $1, $3}' /etc/passwwd

awk 'BEGIN{FS=":"; OFS="---"}NR==2{print $1, $3}' /etc/passwd

awk -F: '$1=="root"{print $0}' /etc/passwd
a=root
awk -F: -v var=$a  '$1==var{print $0}' /etc/passwd

流程控制
if
awk -F: '{if($1=="root") print $1}' /etc/passwd
awk -F: '{if($1=="root") {print $1; print $6}}' /etc/passwd
awk -F: '{if($1=="root") print $1; else print $6}' /etc/passwd
awk -F: '{if($1=="root") print $1; else if($1=="ftp") print $2; else if($1=="mail") print $3; else print NR}' /etc/passwd
awk -F: '{var=($3>=500)?$1:"sys"; print $1 "\t" $3 "\t" var}' /etc/passwd
awk -F: '{if($3==0) print $1, "admin"; else if($3>0 && $3<500) print $1, "sys"; else print $1, "user"}' /etc/passwd

BEGIN END的使用
awk -F: 'BEGIN{i=0}{i++}END{print i}' /etc/passwd
awk -F: 'BEGIN{print NR, NF}' /etc/passwd #读前处理
awk -F: 'END{print NR, NF}' /etc/passwd #读后处理
awk -F: 'BEGIN{i=0}{i+=NF}END{print i}' /etc/passwd
awk -F: 'BEGIN{i=0}$3>=500{print $1; i++}END{print i}' /etc/passwd #显示所有普通用户及其个数

break
continue
next #读取下一行
exit #不再读取下一行, 读取动作终止, 转为执行end语句块

awk 'BEGIN{for(x=1;x<=5;x++){if(x==3) break; print x}}' #continue

awk -F: '{if(NR>3) next; print $1}END{print NR}' /etc/passwd
awk -F: '{if(NR>3) exit; print $1}END{print NR}' /etc/passwd

循环语句
for
awk 'BEGIN{for(x=1; x<=5; x++) print x}'
awk 'BEGIN{for(i=1;i<=3;i++){for(j=1;j<=5;j++) print i, j}}'
awk -F: '{for(x=NF;x>0;x--) print $x}' /etc/passwd
awk -F: '/bash$/{for(x=NF;x>0;x--) printf "%-13s", $x; printf "\n"}' /etc/passwd

while
awk -F: '{while($3<3){print $3, $1; $3++}}' /etc/passwd
awk 'BEGIN{i=1; while(i<10){if(i%2==0)print i; i++}}'

awk中的函数
awk 'BEGIN{print int(3.14159)}' #取整数部分
awk 'BEGIN{x="abcdefg"; print substr(x, 4, 3)}'
awk 'BEGIN{x="abcdefg"; print substr(x, 4)}'

awk 'BEGIN{x="abcdefg"; print length(x)}'
awk 'NR==2{print length($0)}' /etc/passwd #把$0省略也可
awk 'BEGIN{x="abcdefg"; print substr(x, length(x), 1)}'

a="abcdefg"
var=`echo $a | awk '{print substr($0, length($0), 1)}'`

awk 'BEGIN{x="xyzabcxyzabcxyzabc"; sub("abc", "ABC", x); print x}' #sub()改用gsub()

awk读取命令输出(getline, 取得1行)
awk 'BEGIN{print "Enter number: "; getline NUM; for(i=1;i<=NUM;i++) print i}'
awk 'BEGIN{"uname -a" | getline; print $3}'
awk -F: 'BEGIN{while(getline < "/etc/passwd") print $3 "\t" $1}'

echo | awk -F: '{"grep root /etc/passwd" | getline; print $0}' #或打印$1
echo | awk '{"date" | getline; print $0}'

#########

awk字符串拼接(字符串转数字, 数字转字符串) 
awk中数据类型是不需要定义的, 是自适应的, 有时候需要强制转换, 我们可以通过下面操作完成

拼接
awk 'BEGIN{a=100;b=100;c=a""b; print c}'      
100100
awk 'BEGIN{a="aa";b="bb";c=a""b; print c}'      
aabb

awk 'BEGIN{a="a";b="b";c=(a+b);print c}'  
0
+号操作符强制将左右两边的值转为数字类型, 然后进行操作

#########

在awk中使用循环:
echo | awk '{for(i=0; i<=10; i++) print i}'

awk中的数组:
echo | awk '{arr["a"]="aa"; arr["b"]="bb"; arr["c"]="cc"; for(i in arr) print i, arr[i]}'
生成数组
vim file1
111
222
333
444
555
666
awk '{arr[x++]=$1}END{for(i=0;i<NR;i++)print arr[i]}' file1

时间: 2024-10-30 08:59:48

SHELL小总结的相关文章

批量建用户的shell小脚本

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://navyaijm.blog.51cto.com/4647068/880270  一位群友提供的shell批量创建用户的小脚本,我把它记下来: #!/bin/bash for user in `cat /opt/userlist.txt` do      useradd $user      echo linux | passwd --stdin $user      echo "

一个shell小案例(创建日期目录)_linux shell

今天看到一个shell题目,正好拿来练练手 需要在多个目录中 (如:beijing shanghai tianjin guangzhou 等等) 创建子目录(以年份命名),然后进入子目录,新建目录并以当天的日期命名. 最终的效果是这样的: 复制代码 代码如下: china/guangdong/ china/guangdong/shenzhen/2010/1206 china/guangdong/shenzhen/2010/1207 china/guangdong/shenzhen/baoan/2

12个Linux系统高频率命令行和shell小脚本

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dgd2010.blog.51cto.com/1539422/1584952 以下是在部署OpenStack过程中摘录的一些较为常用的命令行或shell脚本,仅供参考. 1.杀死所有存在的僵尸进程 1 2 ps -ef | grep defunc | grep -v grep | awk '{print $3}' | xargs kill -9 #pkill dnsmasq 2.

Shell 小技巧的问题 mysql -e ,字符串替换telnet命令检测

api_url=192.168.1.4:12481 #echo ${api_url/:/ }a #echo `echo $api_url|sed -i 's/:/ /' ` #echo `cat 192.168.1.4:12481|sed -i 's/:/ /' ` #sed 'as/:/ /' (sleep 1;)|telnet ${api_url/:/ }|cat #替换并检测数据 str4=`(sleep 1;echo AA;sleep 1; echo 123; sleep 1; echo

在Linux中使用shell脚本自动创建/移除并挂载交换文件

几天前我们写了一篇关于在 Linux 中 3 种创建交换文件的方法,它们是常见的方法,但是需要人工操作. 今天我发现了一个 Gary Stafford[1] 写的 shell 小脚本(两个 shell 脚本,一个用于创建交换文件,另外一个用于移除交换文件),它可以帮助我们在 Linux 中创建/移除并且自动挂载交换文件. 默认这个脚本创建并挂载 512MB 的交换文件.如果你想要更多的交换空间和不同的文件名,你需要相应地修改脚本.修改脚本不是一件困难的事,因为这是一个容易上手而且很小的脚本. 推

Spark:大数据的“电光石火”

Spark已正式申请加入Apache孵化器,从灵机一闪的实验室"电火花"成长为大数据技术平台中异军突起的新锐.本文主要讲述Spark的设计思想.Spark如其名,展现了大数据不常见的"电光石火".具体特点概括为"轻.快.灵和巧". 轻:Spark 0.6核心代码有2万行,Hadoop 1.0为9万行,2.0为22万行.一方面,感谢Scala语言的简洁和丰富表达力:另一方面,Spark很好地利用了Hadoop和Mesos(伯克利 另一个进入孵化器的

linux bash 和 sh的区别

Linux 中的 shell 有很多类型,其中最常用的几种是: Bourne shell (sh).C shell (csh) 和 Korn shell (ksh), 各有优缺点.Bourne shell 是 UNIX 最初使用的 shell,并且在每种 UNIX 上都可以使用, 在 shell 编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell.Linux 操作系统缺省的 shell 是Bourne Again shell,它是 Bourne shell 的扩展,简称 Bas

Spark:大数据时代的电光火石

Spark是发源于美国加州大学伯克利分校AMPLab的集群计算平台.它立足于内存计算,从多迭代批量处理出发,兼收并蓄数据仓库.流处理和图计算等多种计算范式,是罕见的全能选手. Spark已正式申请加入Apache孵化器,从灵机一闪的实验室"电火花"成长为大数据技术平台中异军突起的新锐.本文主要讲述Spark的设计思想.Spark如其名,展现了大数据不常见的"电光石火".具体特点概括为"轻.快.灵和巧". 轻:Spark 0.6核心代码有2万行,H

一个shell脚本编写小助手

功能: 1.自动检测否存在同名文件,存在则提示用户存在,并给出编辑,删除后创建,和退出3个选项 2.自动添加脚本版权信息(有自定义和默认2种方式) 3. 自动检测有无语法错误:如果有语法错误则提示用户是否退出,不退出则打开vim修改,直到修改正确为止 4.脚本编写成功后自动添加执行权限 用法: 执行脚本后面添加脚本名称即可 #!/bin/bash #:-------------CopyRight------------- #:Name:lustlost - 1.0 #:Date:2012-7-1