shell杂记1

变量

进程结束,变量被销毁
普通变量,子进程中是无法访问的,得是环境变量才行
作用域:当前脚本中得为全局变量,环境变量为超全局,函数内得为局部
export varname=value  声明并赋值一个环境变量
name=xqw  定义赋值一个普通变量  export name  再声明为环境变量
局部变量  local varname=val
位置变量  $1  $2  ...  引用脚本的参数
变量的命名:仅包含数字,字母,下划线,不能以数字开头;不能跟已有的环境变量重名
$?   上一个进程(执行的命令)的执行状态返回值

执行程序,有两种返回
    结果
    状态  $?  如果是正确被执行,则返回0, 如果是错误,则1~25512127系统保留)

脚本执行时,启动一个新bash
    命令行直接执行的,相当于当前bash的子bash,会继承父进程的环境变量
    系统自动执行的脚本,是需要设置环境变量的,因为执行时,并没有上层的父bash进程

unset varname  销毁变量
set 
printenv
env
export
export PATH=$PATH:/bin/go 

shell中变量的值默认是字符串,并不能直接算术运算

执行脚本

./xx.sh 
xx.sh  要将路径加入到PATH中
bash xx.sh  
source xx.sh  
. xx.sh 

判断表达式

[ expression ]
[[ expression ]]
test expression

-eq  -ne  -gt  -ge  -lt  -le 

[ $a -eq $b ]
echo $?

逻辑判断

&&    
短路现象: a && b   a为真,则执行后面的b , a为假,则b不用执行
id user3 &> /dev/null && echo 'user3 is exists.'

|| 
短路现象: a || b    a为真,则后面的不用判断,a为假,则需要执行后面的
id root &> /dev/null || echo 'root not exists.' && echo 'root is exists.'

如果用户不存在,就添加用户?
    id user2 &> /dev/null || useradd user2 
    ! id user3 &> /dev/null && useradd user3 

判断文件超过100行,就是大文件?
[ `wc -l ./passwd | cut -d' ' -f1` -gt 100 ] && echo 'big file.' || echo 'small file.'

!id user1 && useradd user1 && echo 'user1' | passwd --stdin user1 || echo 'user1 exists.'

exit  退出当前进程脚本  
exit 可以定义执行状态结果是什么;如果没有定义,则默认把exit前面那一条命令的退出执行状态当作整个脚本的执行状态结果  
exit #   

运算

let C=$A+$B
C=$[$A+$B]
C=$(($A+$B))
C=`expr $A + $B`   expr命令 算术运算表达式   表达式中各操作数及运算符之间要有空格,而且要使用命令引用

文件测试

-e  -f  -d  -r  -w  -x 
[ -e file ]
[ -x file ]

脚本调试

bash -n xx.sh   检查语法,不执行脚本
bash -x xx.sh   单步,显示每一条执行的命令

注意:如果脚本中没有定义退出码,则最后执行的那一条命令的状态码,就是整个脚本的退出状态码

shift

执行其一次,$1 $2 $3 ... 位置变量的值整体向前移动一位
shift #  向前移动#位

特殊变量

$?   
$1  $2  
$#  参数个数
$*   $@   参数列表

练习

1. 传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来,
要求保留两位精度,形如:./calc.sh 5 / 2
echo "scale=2;111/22" | bc
bc <<< "scale=2;111/22"

2. 传递3个参数给脚本,参数均为用户名,将此些用户的账号信息提取出来后,放置于 /tmp/testusers.txt文件中,并要求每一行行首有行号;

3. 判断当前主机的cpu生产商,其信息在/proc/cpuinfo文件中 vendor_id 一行中,
如果其生产商为AuthenticAMD,就显示其为AMD公司;
如果其生产商为GenuineIntel,就显示其为Intel公司;
否则,就说其为非主流公司;
cputype=`grep 'vendor_id' /proc/cpuinfo | head -1 | cut -d':' -f2 | sed -r 's@[[:space:]]+@@g'`

case $cputype in
AuthenticAMD)
    echo "AMD."
    ;;
GenuineIntel)
    echo "intel."
    ;;
*)
    ehco "is not popular company.";;
esac

4. 给脚本传递三个整数,判断其中的最大数 和 最小数,并显示出来;

5. 写脚本,添加5个用户,user1~user5,每个用户的密码同用户名,用户添加完成后,显示用户成功添加
useradd user1 &> /dev/null && echo user1 | passwd --stdin user1 &> /dev/null && echo 'user1 add success.' || echo 'user1 exists.'

for i in {1..5}; do
    if id user$i &> /dev/null; then
        echo "user$i exists."
    else
        useradd user$i
        echo "user$i" | passwd --stdin user$i &> /dev/null
        echo "add user$i success."    
    fi
done

6. 添加3个用户,先判断其是否存在,不存在才添加,添加完成后,显示一共添加了几个用户,最后显示当前系统上共有多少个用户?

7. 给定一个用户,如果其uid为0,就显示为管理员,否则就显示其为普通用户

8. 删除某用户,一并删除其家目录,显示删除完成

9. 判断当前系统上是否有用户的默认shell为bash,如果有,就显示有多少个这类用户;否则,就显示没有这类用户;

10. 判断当前系统上是否有用户的默认shell为bash;如果有,就显示其中一个的用户名;否则,就显示没有这类用户;
11. 给定一个文件,判断这个文件中是否有空白行,如果有,则显示其空白行数,否则,显示没有空白行;
12. 给定一个用户,判断其UIDGID是否一样,如果一样,就显示此用户为“good guy”,否则,就显示此用户为“bad guy” , 进一步要求,不使用id命令获得其id号
13. 传递两个参数,显示两者之积,之和?
14. 不使用id命令,判断用户是否存在,并且判断其uid,gid是否一样
USERNAME=user1
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then
  echo "No such user: $USERNAME."
  exit 1
fi

USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`
GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`
if [ $USERID -eq $GROUPID ]; then
  echo "Good guy."
else
  echo "Bad guy."
fi
本作品采用《CC 协议》,转载必须注明作者和本文链接
六月的风
Junwind
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!