Shell执行方式
Copy bash hello.sh #方式一
cat hello.sh | bash #方式二
bash < hello.sh #方式三
chmod +x hello.sh #方式四
#方式五
source hello.sh
#source有一个简写形式,可以使用一个点(.)来表示。
#方式六,远程加载执行
curl -s http://localhost/hello.sh | bash
#wget方式
wget -qO - http://localhost/hello.sh | bash
配置文件
全局,针对所有用户
Copy /etc/profile
/etc/profile.d/*.sh
/etc/bashrc
#只针对个人
~ /.bash_profile
~ /.bashrc
环境变量
常用环境变量
BASHPID:Bash 进程的进程 ID。
DISPLAY:图形环境的显示器名字,通常是:0,表示 X Server 的第一个显示器。
IFS:词与词之间的分隔符,默认为空格。
LANG:字符集以及语言编码,比如zh_CN.UTF-8。
PATH:由冒号分开的目录列表,当输入可执行程序名后,会搜索这个目录列表。
SHELL:Shell 的名字。
SHELLOPTS:启动当前 Shell 的set命令的参数,参见《set 命令》一章。
TERM:终端类型名,即终端仿真器所用的协议。
内置变量:PS1,PATH,UID,HOSTNAME,$$,BASHPID,PPID,$?,HISTSIZE
位置、特殊变量
$1,$2 #对应参数
$0 #命令本身
$* #全部参数命为一个字符串
$@ #每个参数为独立字符串
$# #传递给脚本的参数的个数
$? #0代表成功
$? 值 1-255 #代表失败
$$ #当前SHell的进程ID
$_ #为上一个命令的最后一个参数
$! #为最后一个后台执行的异步命令的进程ID
$- #当前Shell启动参数
$? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值。
用户自定义变量
Copy #直接字串
name = 'root'
#变量引用
name = "$USER"
#命令引用
name = ` COMMAND ` 或 name= $( COMMAND )
变量引用
· $name
弱引用,变量引用会被替换为变量值
· ${name}
强引用,不会替换为变量值,保持原字符
如果变量的值本身也是变量,使用${!varname}读取最终的值
Copy #环境变量,可用变量传递给子Shll
export name = VALUE
declare -x name = VALUE
#删除变量
unset NAME
#只读变量,常量
readonly [-p]
declare -r
脚本调试
Copy #只检测语法错误
bash -n hello.sh
#调试并执行
bash -x hello.sh
字符串操作
Copy #获取字符串长度
${ # varname}
#子字符串
${varname : offset : length}
#搜索和替换
myccav = /home/ccav/book/administrator.ini
##最短匹配
echo ${myccav #/*/ }
ccav/book/administrator.ini
##最长匹配
echo ${myccav ##/*/ }
administrator.ini
##只留文件名
echo ${myccav ##*/ }
#替换,将administrator替换为root,加//替换所有
echo ${myccav / administrator / root}
#转换大写
${varname^^}
#转换小写
${varname,,}
判断
注意 [ ] 需要空格,否则会报错误
[ ]和[ [ ] ]的区别是,双括号是增加版,支持正则表达式和通配符
Copy #判断后缀
[[ "$FILE" == * .log ]]
#判断合法非负整数
[[ "$N" =~ ^[0-9]+$ ]]
#判断合法IP
[[ "$IP" =~ ^([ 0 - 9 ]{ 1 , 3 }\.){ 3 }[0-9]{1,3}$ ]]
[[ $IP =~ ^(([ 1 - 9 ] ? [ 0 - 9 ] | 1 [ 0 - 9 ]{ 2 } | 2 [ 0 - 4 ][ 0 - 9 ] | 25 [ 0 - 5 ])\.){ 3 }([ 1 - 9 ] ? [ 0 - 9 ] | 1 [ 0 - 9 ]{ 2 } | 2 [ 0 - 4 ][ 0 - 9 ] | 25 [ 0 - 5 ])$ ]]
Copy -eq 是否等于
-ne 是否不等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于
-z 字符串是否为空
-n 字符串是否不为空
#判断文件
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
#文件权限
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
read
-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d '字符' -t N 输入结束符 TIMEOUT为N秒
Copy #输入
read -p "Input Password:" PASSWORD
echo $PASSWORD
#判断输入Yes
read -p "Yes or No:" ANSWER
[[ $ANSWER =~ ^([Yy] | [Yy][Ee][Ss])$ ]] && echo "Yes" || echo "No"
answer = ` echo $input | tr 'A-Z' 'a-z'`
[ $answer = 'yes' -o $answer = 'y' ] && echo YES
[ $answer = 'no' -o $answer = 'n' ] && echo NO
流程控制
Copy #单分支
if 判断条件 ; then 条件为真的分支代码
fi
#双分支
if 判断条件 ; then 条件为真的分支代码
else
条件为假的分支代码
fi
#多分支
if 判断条件1 ; then 条件1为真的分支代码
elif 判断条件2 ; then 条件2为真的分支代码
elif 判断条件3 ; then 条件3为真的分支代码
...
else
以上条件都为假的分支代码
fi
条件判断case语句
Copy case 变量引用 in PAT1 )
分支1
;; PAT2 )
分支2
;; ...
* )
;;
esac
例子:
case $INPUT in
[yY] | [Yy][Ee][Ss] )
echo "Yes"
;;
[Nn] | [Nn][Oo] )
echo "No"
;;
*)
;;
easc
#case多分支
case $option in
1 )
select parameter in "a" "b" ; do
case $parameter in
a )
echo "aaaa"
break
;;
b )
echo "bbbb"
break
;;
easc
2 )
...
easc
nmap扫描脚本
nmap 127.0.0.0.1
nmap -sV -Pn 127.0.0.1 -v -n
read -p "Input Target:" target
case options in
1 )
nmap -sV -Pn $target -v -n
;;
2 )
nmap -sV -Pn -p 1-1024,7000-9000 $target -v -n
;;
3 )
nmap -sV -Pn -p1-65535 $target -v -n
;;
4 )
nmap -O -Pn $target
;;
esac
循环
Copy #方式1
for 变量名 in 列表; do
循环体
done
#方式2
for 变量名 in 列表
do
循环体
done
#批量创建用户并设置密码
for i in { 1..10} ; do
useradd user $i
PASS = ` cat /dev/urandom | tr -dc '[:alnum:]' | head -c12 `
echo $PASS | passwd --stdin user $i & > /dev/null
echo user $i : $PASS >> /data/user.log
echo "user$i is created"
done
#扫描存活
#!/usr/bin/env bash
for ip in { 1..254} ; do
ping 192.168. $ip .1 -c 1 | grep -q "ttl=" && echo "192.168.$ip.1 yes" >> /usr/tmp/.sys.log & > /dev/null 2>&1 ;
done
wait
定义函数
Copy #语法一
func_name () {
.. .函数体. ..
}
#语法二
function func_name {
.. .函数体. ..
}
#语法三
function func_name () {
.. .函数体. ..
}
查看函数、删除
#查看已定义函数名
declare -F
#查看函数内容
declare -f
#查看函数内容
declare -f func_name
#删除函数
unset func_name
函数调用
#直接写函数名
#调用其它脚本中的函数
. filename
or
source filename
防火墙禁用
#防火墙禁用
disable_firewall () {
systemctl disable --now firewalld & > /dev/null
echo "防火墙已禁用"
}
扫描目录
#扫描目录
function dirb ()
{
PORT = "80"
/usr/bin/dirb http:// $IP : $PORT /usr/share/dirb/wordlists/common.txt
}