打开kali,Xshell连接
一、脚本创建执行与变量使用
vim 1.sh
可利用 #! /bin/bash, #! /bin/dash ,#! bin/sh
这三种脚本解释器不论哪种,最终都是调用 dash
在1.sh内加入内容,尝试执行,./1.sh,但需要加权
或者,在不使用加权的情况下,使用 sh 1.sh 或者 bash 1.sh
指定要执行的脚本文件路径即可
再者,使用 source 1.sh
和 sh 1.sh 差不多,只是 source 命令多了颜色加深标注
变量的使用
1.声明,输出
不加引号和加双引号都是输出变量,加单引号则直接把 $love 打印出来
2.变量拼接
变量一般由数字,字母,下划线组成,但不能以数字开头,如 9name ,变量里也最好不要有空格
以上全部均为临时变量,使用 set | grep love 查看变量
unset love 删除变量
之后可以看到 love 变量没有了
补充
二、永久环境变量和字符串操作
永久变量
对于 $PATH 环境变量,当我们执行 ls 时,会现在其 /usr/bin 下找到 ls 脚本然后执行。
将可执行脚本添加到环境变量存在的文件夹下
1.直接移动或者复制
ma 2.sh /usr/bin
2.将整个文件夹添加
export PATH=/root/demo:$PATH -添加到头部
export PATH=$PATH:/root/demo -添加到尾部
export 详解
"""
Linux是一个开源的类Unix操作系统,它基于POSIX标准,export 命令在 Linux 中用于设置或导出环境变量,使其在当前会话中可用,并且可以在子进程中继承。环境变量是在操作系统中定义的变量,它们可以控制程序的行为,存储配置信息等。以下是 `export` 命令的一些基本用法:
1. 导出单个变量:
export VAR=value
这条命令会创建一个新的环境变量 `VAR` 并赋予它值 `value`。2. 导出多个变量:
export VAR1=value1 VAR2=value2
这条命令会同时导出多个环境变量。3. 导出所有变量:
export
不带任何参数的 `export` 命令会显示当前会话中所有已导出的环境变量。4. 导出命令的输出:
export VAR=$(command)
这条命令会将 `command` 命令的输出赋值给环境变量 `VAR`。5. 在脚本中使用:
在 shell 脚本中使用 `export` 可以确保脚本中设置的环境变量在脚本执行完毕后仍然可用。6. 持久化环境变量:
要使环境变量在系统重启后仍然有效,需要将它们添加到 `/etc/profile`、`~/.bash_profile`、`~/.bashrc` 或其他适当的 shell 配置文件中。请注意,使用 `export` 设置的环境变量只对当前会话和子进程有效。如果你想要永久设置环境变量,你需要将它们添加到用户的 shell 配置文件中,这样每次新的会话开始时,这些变量就会被自动加载。
"""
3.持久化环境变量
vim ~/.bashrc
写入 export PATH=$PATH:/root/demo
source ~/.bashrc -保存并加载配置文件
source 详解
"""
source 命令在 Linux 和 Unix 系统中用于执行当前 shell 环境中的脚本文件,而不是在新的子 shell 中执行。这意味着 source 命令会读取指定的脚本文件,并在其执行的 shell 环境中执行脚本中的命令。source 命令的基本用法如下:
1. 执行当前目录下的脚本:
source script.sh2. 执行指定目录下的脚本:
source /path/to/script.shsource 命令与 . 命令是等价的,两者都可以用于在当前 shell 环境中执行脚本。这与直接调用脚本文件不同,后者会在新的子 shell 中执行脚本,因此对当前 shell 环境的任何更改(如变量赋值或别名设置)都不会反映到原始 shell 环境中。
source 命令常用于执行配置脚本,如 .bashrc 或 .profile,这些脚本用于设置用户的 shell 环境。
"""
字符串基本操作
1.读取字符串长度
str="You coward!"
echo ${#str}
2.字符切片
echo ${str:0:3}
从0位置开始截取三个字符,You
在 Bash 中,`dquote>` 是一个内置的命令,用于处理双引号内的字符串。当你在命令行中输入 `dquote>` 并跟随一个字符串时,它会将字符串中的双引号去掉,并打印出结果。
对于你给出的字符串 `"You coward!"`,使用 `dquote>` 的效果如下:
```bash
dquote> "You coward!"
```输出将会是:
```
You coward!
```双引号被移除了,字符串中的其他部分保持不变。这个命令在处理文本和脚本中的字符串时非常有用,尤其是在自动化脚本中需要去除或添加引号时。
三、脚本参数传递与数学运算
"""
在 Linux 下的 shell 脚本中,参数传递和数学运算是两个基本而重要的概念。1. 脚本参数传递:
当在命令行中执行一个 shell 脚本时,可以传递参数给脚本。这些参数在脚本中可以通过特殊变量 $1, $2, ..., $n 访问,其中 $1 是第一个参数,$2 是第二个参数,以此类推。特殊变量 $# 用于获取传递给脚本的参数总数,$@ 和 $* 用于获取所有参数的列表,$0用于获取文件名,$$用于获取进程id例子:
#!/bin/bashecho "The name of file:$0"
echo "Number of arguments: $#"
echo "All arguments: $*"
echo "All arguments (quoted): $@"echo "The first argument is $1"
echo "The second argumnet is $2"
echo "The process_id is $$"
2. 数学运算:
shell 脚本中进行数学运算可以通过多种方式实现:a. 使用 $(( )):
这是最常用的方法,用于执行算术运算。
例子:
#!/bin/bash
sum=$((1 + 2))
echo "Sum is $sum"b. 使用 expr:
expr 是一个命令行工具,用于执行简单的算术运算。
例子:
#!/bin/bash
sum=$(expr 1 + 2)
echo "Sum is $sum"注意:在进行数学运算时,要确保数值是整数,因为 shell 脚本不支持浮点数运算。
"""
参数传递
数学运算
四、脚本与用户交互及if条件判断
"""
在 Linux 下,shell 脚本可以通过读取用户的输入来实现与用户的交互,并使用 if 条件判断来根据输入或其他条件执行不同的脚本逻辑。1. 脚本与用户交互:
脚本可以通过 `read` 命令与用户进行交互,获取用户的输入。`read` 命令后面可以跟一个或多个变量,用于存储用户的输入。例子:
#!/bin/bash
echo "Please enter your name:"
read name
echo "Hello, $name!"`read` 命令还可以指定分隔符和读取的行数,例如 `read -p "Prompt: " var` 会在用户输入后显示提示信息。
2. if 条件判断:
if 条件判断是 shell 脚本中控制流的重要组成部分,它允许脚本根据不同的条件执行不同的命令。基本语法:
if [ condition ]; then
# 条件为真时执行的命令
elif [ another_condition ]; then
# 另一个条件为真时执行的命令
else
# 所有条件都不为真时执行的命令
fi条件可以是字符串比较、数值比较、文件测试等。条件测试使用方括号 `[ ]` 或者 `[[ ]]`,后者提供了更多的灵活性和功能。
例子:
#!/bin/bash
echo "Enter a number:"
read num
if [ "$num" -gt 10 ]; then
echo "The number is greater than 10."
elif [ "$num" -eq 10 ]; then
echo "The number is equal to 10."
else
echo "The number is less than 10."
fi注意:在使用条件测试时,要确保使用正确的比较运算符和测试符号。
在 Linux shell 脚本中,这些是用于数值比较的测试运算符:
- `-eq`:等于(equal)。用于检查左边的值是否等于右边的值。
- 例子:`[ 5 -eq 5 ]` 返回 `0`(真),因为 5 等于 5。- `-lt`:小于(less than)。用于检查左边的值是否小于右边的值。
- 例子:`[ 3 -lt 5 ]` 返回 `0`(真),因为 3 小于 5。- `-gt`:大于(greater than)。用于检查左边的值是否大于右边的值。
- 例子:`[ 7 -gt 5 ]` 返回 `0`(真),因为 7 大于 5。- `-ne`:不等于(not equal)。用于检查左边的值是否不等于右边的值。
- 例子:`[ 4 -ne 5 ]` 返回 `0`(真),因为 4 不等于 5。这些运算符通常用在 `test` 命令中,或者用在 `[[ ]]` 复合命令中,用于执行条件测试。在 shell 脚本中,这些比较运算符非常有用,特别是在需要根据数值条件执行不同操作的场景中。
-s 用于避免在终端显示密码
这里是进行的字符串比较
报错,因为这里有些语法是 bash 特有的(比如说read -s),只需将脚本解释器换成 #! /bin/bash
测试
#!/bin/bash
read -p "Please enter your password: " password1
read -p "Check your password: " password2
if [ "$password1" = "$password2" ]; then
echo "Register successfully!"
else
echo "Password not equal!"
fi
五、字符串运算符和逻辑运算符
"""
Shell脚本中的字符串运算符和逻辑运算符用于执行字符串比较和逻辑判断。1. 字符串运算符:
- "=" 和 "==":用于比较两个字符串是否相等。
示例:[ "$str1" = "$str2" ] 或 [ "$str1" == "$str2" ]
- "!=":用于比较两个字符串是否不相等。
示例:[ "$str1" != "$str2" ]
- "-z":检查字符串是否为空。
示例:[ -z "$str" ] 如果 $str 为空,则条件为真。
- "-n":检查字符串是否非空。
示例:[ -n "$str" ] 如果 $str 非空,则条件为真。2. 逻辑运算符:
- "&&":逻辑与运算符,用于连接两个命令,只有当两个命令都成功执行时,整个表达式才为真。
示例:command1 && command2
- "||":逻辑或运算符,用于连接两个命令,只要有一个命令成功执行,整个表达式就为真。
示例:command1 || command2
- "!":逻辑非运算符,用于反转命令的执行结果,如果命令执行失败,则整个表达式为真。
示例:! command这些运算符在编写条件语句和控制脚本流程时非常有用。
"""
"""
在 Shell 脚本中,-a 和 -o 是用于逻辑判断的运算符,它们在 [ ] 或者 [[ ]] 测试表达式中用来连接多个条件。1. -a(AND)运算符:
-a 运算符用于连接两个条件,并且只有当两个条件都为真时,整个表达式的结果才为真。
例如:[ "$str1" = "$str2" -a "$str3" = "$str4" ]2. -o(OR)运算符:
-o 运算符用于连接两个条件,只要有一个条件为真,整个表达式的结果就为真。
例如:[ "$str1" = "$str2" -o "$str3" = "$str4" ]这些运算符在 [ ] 测试中使用时,需要在条件表达式的两边加上空格。而在 [[ ]] 测试中,可以使用逻辑运算符 && 和 ||,它们分别对应 -a 和 -o 的功能,并且更加现代和易于阅读。
"""
例子
#!/bin/bash
# 提示用户输入用户名和密码
read -p "Please enter your username: " username
read -p "Please enter your password: " password
read -p "Please confirm your password: " confirm_password# 检查用户名是否包含不允许的字符
if [[ "$username" == *"@"* || "$username" == *" "* ]]; then
echo "Error: Username cannot contain '@' or spaces."
exit 1
fi# 检查密码强度(例如,至少8个字符,包含数字和大写字母)
if [[ "${#password}" -lt 8 || ! "$password" =~ [0-9] || ! "$password" =~ [A-Z] ]]; then
echo "Error: Password must be at least 8 characters long and include a number and an uppercase letter."
exit 1
fi# 检查两次输入的密码是否一致
if [ "$password" = "$confirm_password" ]; then
echo "Passwords match. Registration successful!"
else
echo "Error: Passwords do not match."
exit 1
fi# 如果所有检查都通过,可以继续进行注册或其他操作
echo "User $username registered successfully with password $password."
解析
- 使用
read
命令提示用户输入用户名和两次密码。- 使用
[[ ]]
和*
通配符检查用户名是否包含不允许的字符(如 "@" 或空格)。- 使用
${#password}
获取密码长度,并使用=~
正则表达式运算符检查密码是否包含数字和大写字母。- 使用
=
运算符比较两次输入的密码是否一致。- 如果所有条件都满足,脚本将输出注册成功的消息;如果任何条件不满足,脚本将输出错误消息并退出。
补充
在 shell 脚本中,[[ ]]
是一个扩展的测试命令,用于评估条件表达式。它是 test
命令(使用 [ ]
)的增强版本,提供了更多的功能和更好的性能
[[ "str" =~ pattern ]] 用于正则匹配
六、for循环,while循环
"""
在 shell 脚本中,`for` 循环和 `while` 循环是两种基本的循环结构,用于重复执行一系列命令。For 循环用于在一系列值上进行迭代。它的形式如下:
for variable in list
do
commands
done- variable:在每次迭代中被赋值为列表中的下一个元素的变量。
- list:一个由空格分隔的值的集合,可以是数字序列或任何其他元素。
- commands:在每次迭代中执行的命令。示例 1: 数字序列
#!/bin/bash
for i in {1..5}
do
echo "Iteration $i"
done示例 2: 列表
#!/bin/bash
for color in Red Green Blue Yellow
do
echo "$color is a color of the rainbow"
doneWhile 循环用于在条件为真时重复执行一系列命令。它的形式如下:
while condition
do
commands
done- condition:一个表达式,如果为真(非零状态),则执行循环体中的命令。
- commands:在条件为真时执行的命令。示例 1: 计数器
#!/bin/bash
i=1
while [ "$i" -le 5 ]
do
echo "Count $i"
let i+=1
done示例 2: 用户输入
#!/bin/bash
echo "Enter 'q' to quit."
while read -r -p "Enter a number: " num
do
if [[ "$num" == 'q' ]]; then
break
fi
echo "You entered $num"
doneC-style For 循环
在 Bash 中,还可以使用 C 风格的 `for` 循环:for ((i=0; i<5; i++))
do
echo "Iteration $i"
done注意事项:
- 在 `for` 循环中,如果列表为空,循环体将不会执行。
- 在 `while` 循环中,如果初始条件为假,循环体将不会执行。
- 可以使用 `break` 命令提前退出循环,或者使用 `continue` 命令跳过当前迭代,继续下一次循环。
- 循环可以嵌套,即在一个循环内部可以包含另一个循环。
"""
例子
str.sh
for str in "Hello world"
echo "$str"
done
图片中显示的是一个 Bash shell 脚本的片段,它使用了一个 `for` 循环来迭代字符串 "Hello world" 中的每个字符,并打印出来。下面是脚本的逐行解释:
1. `for str in "Hello world"`:这行定义了一个 `for` 循环,其中 `str` 是循环变量,它将依次取得字符串 "Hello world" 中的每个字符。注意,这里的双引号确保了整个字符串作为一个整体被处理,而不是被 shell 解释为多个单词。
2. `do`:这行标志着循环体的开始,`do` 和 `done` 之间的命令会在每次迭代中执行。
3. `echo $str`:这是循环体内的命令,它使用 `echo` 命令打印出当前迭代的变量 `str` 的值,即 "Hello world" 中的当前字符。
4. `done`:这行标志着循环体的结束。
然而,这个脚本有一个问题:它不会按预期工作。在 Bash 中,`for` 循环默认不会将字符串分割成单个字符。相反,它会将整个字符串作为一个单一的迭代项。如果你想要迭代字符串中的每个字符,你需要使用其他方法,比如使用 `while` 循环和 `read` 命令的 `-r` 选项来逐字符读取,或者使用 Bash 的内置功能 `mapfile` 或 `readarray`。
例如,使用 `while` 循环和 `read` 命令来迭代每个字符的正确脚本如下:
```bash
#!/bin/bash
str="Hello world"
while IFS= read -r -n 1 char; do
echo "$char"
done <<< "$str"
```在这个修正后的脚本中,`IFS=` 禁止了字段分隔符的默认行为,`-n 1` 告诉 `read` 命令每次只读取一个字符,`<<< "$str"` 是一个 here-string,它将 `str` 变量的内容传递给 `while` 循环。
7.sh
for (( i=1; i<10; i++ ))
do
echo $i
done
8.sh
i=1
while(( $i<=10 ))
do
echo $i
let "i++"
done
或者
i=1
while(( $i<=10 ))
do
echo $i
((i++))
done
let 命令主要用于算术运算
六、until循环以及函数基本创建调用
'until' 循环在 shell 脚本中用于重复执行一系列命令,直到指定的条件为真(非零状态)才退出循环。这与 'while' 循环相反,'while' 循环是在条件为真时执行循环体。'until' 循环至少执行一次,即使条件最初为假。
基本语法:
until condition
do
commands
donecondition:一个表达式,如果为真(非零状态),则退出循环。
commands:在条件为假时重复执行的命令。示例:
#!/bin/bash
i=1
until [ "$i" -gt 5 ]
do
echo "Counting: $i"
let i+=1
doneecho "Done!"
函数基本创建与调用
在 shell 脚本中,函数是一种将代码块封装起来,以便可以重复调用的结构。使用函数可以提高代码的可读性和可维护性。
创建函数:
function_name() {
# 函数体:在这里编写函数要执行的命令
commands
}或者使用 'function' 关键字:
function function_name {
# 函数体:在这里编写函数要执行的命令
commands
}调用函数:
function_name示例:
#!/bin/bash# 创建一个函数,用于打印问候语
greet() {
echo "Hello, $1!" # $1 是传递给函数的第一个参数
}# 调用函数,传递用户名作为参数
greet "World"# 创建另一个函数,用于计算两个数的和
add() {
local a=$1
local b=$2
echo $((a + b))
}# 调用函数,传递两个数字作为参数
result=$(add 3 4)
echo "The sum is: $result"
例子
9.sh
#! /bin/bash
i=10
until [[ "$i" -gt 20 ]]
do
echo $i
((i++))
done
echo "Done!"
10.sh
Great(){
echo "hello, $1"
echo "Welcome to the world!"
}
read -p "Please enter your name" name
Great $name
七、重定向操作和不同脚本的相互调用
一、重定向操作
在 shell 脚本中,重定向操作用于改变命令的输入和输出流。这允许你将输出发送到文件、从文件读取输入或合并输出流。
1. 输出重定向:
- `command > file`:将命令的输出重定向到文件,如果文件存在则覆盖。
- `command >> file`:将命令的输出追加到文件末尾。2. 输入重定向:
- `command < file`:从文件读取输入到命令。3. 错误重定向:
- `command 2> file`:将错误输出重定向到文件。
- `command 2>> file`:将错误输出追加到文件末尾。4. 同时重定向输出和错误:
- `command &> file`:将标准输出和错误输出都重定向到文件。5. 合并输出流:
- `command1 2>&1`:将错误输出合并到标准输出。6. 管道操作:
- `command1 | command2`:将 `command1` 的输出作为 `command2` 的输入。示例:
#!/bin/bash
echo "Hello, World!" > output.txt
cat input.txt | sort > sorted.txt 2> error.log二、不同脚本的相互调用
在 shell 脚本中,你可以通过以下几种方式调用其他脚本:
1. 直接调用:
- `source script.sh`:在当前 shell 环境中执行脚本,变量和函数在脚本执行后仍然可用。
- `. script.sh`:与 `source` 相同,使用点命令执行脚本。2. 子 shell 调用:
- `bash script.sh` 或 `sh script.sh`:在新的子 shell 中执行脚本,变量和函数在脚本执行后不会影响当前环境。3. 命令替换:
- `output=$(script.sh)`:执行脚本并将输出赋值给变量。4. 管道调用:
- `command1 | script.sh`:将 `command1` 的输出作为 `script.sh` 的输入。5. 作为命令参数传递:
- `script.sh arg1 arg2`:将参数传递给脚本。示例:
#!/bin/bash
# 调用另一个脚本并传递参数
./another_script.sh param1 param2# 调用另一个脚本并捕获输出
output=$(./another_script.sh)
echo "Output: $output"
例子
11.sh
thing="I love u"
time="forever"
echo $thing $time
12.sh
source 11.sh
ls > /dev/null
将 ls 命令的输出重定向到垃圾站
mkdir -p dir1/123/1/2
mkdir -p dir2/456/5/6
#dir.txt
/home/demo/dir1
/home/demo/dir2
ls -l < dir.txt
< dir.txt
是一个输入重定向,它将 dir.txt
文件中的内容作为 ls
命令的输入。这意味着 dir.txt
应该包含一系列目录的路径,每个路径占一行。
文件描述符
0 1 2
0 标准输入
1 标准输出
2 错误输出
例子
ls > 520.txt 2>1314.txt
输出正确,结果存储在 520.txt 中
l > 520.txt 2 >1314.txt
输出错误,结果存到1314.txt中
写在最后:
这些只是最基本的shell脚本基础,甚至不知道学了有什么用,也许仅作入门kali linux。
作为一个刚入门的渗透测试(Penetration Testing,简称 PenTest)工程师,学习 Shell 编程对你来说有以下几个方面的用处:
1. 自动化渗透测试流程:Shell 脚本可以帮助你自动化重复性的渗透测试任务,如端口扫描、服务识别、漏洞扫描等。
2. 定制化工具:通过 Shell 编程,你可以编写定制化的脚本,以适应特定的渗透测试需求,这些需求可能不会被现有的工具完全覆盖。
3. 快速原型开发:Shell 脚本提供了一种快速开发和测试渗透测试工具和策略的方法。
4. 数据处理和分析:在渗透测试过程中,你可能需要处理和分析大量的数据。Shell 脚本可以帮助你过滤、排序和提取关键信息。
5. 报告生成:Shell 脚本可以自动化生成渗透测试报告的过程,包括收集测试结果、格式化输出和生成图表。
6. 环境设置:在开始渗透测试之前,你可能需要设置特定的测试环境。Shell 脚本可以帮助你快速配置这些环境。
7. 学习基础:Shell 编程是学习更高级编程语言和渗透测试技能的基础。它有助于你理解编程逻辑、流程控制和脚本语言的基本概念。
8. 提高效率:通过编写 Shell 脚本,你可以减少手动执行任务的时间,从而提高工作效率。
9. 模拟攻击:Shell 脚本可以用来模拟攻击场景,帮助理解攻击者可能采取的行动路径。
10. 学习操作系统:Shell 编程深入到操作系统的命令行界面,这有助于你更深入地了解操作系统的工作原理,这对于渗透测试至关重要。
11. 掌握常用工具:Shell 脚本经常与各种命令行工具一起使用,如 `nc`(Netcat)、`nmap`、`metasploit` 等,这些工具在渗透测试中非常常用。
12. 增强问题解决能力:通过编写和调试 Shell 脚本,你可以提高解决问题的能力,这是渗透测试工程师的核心技能之一。
总之,Shell 编程对于渗透测试工程师来说是一个宝贵的技能,它不仅可以提高你的工作效率,还可以帮助你更深入地理解系统和网络的工作原理,从而在渗透测试领域更加专业和高效。