1.简述如何调试 Shell 脚本?
调试 Shell 脚本是一个帮助开发者识别和修正脚本中错误的过程。Bash 提供了多种方式来调试脚本,其中包括:
-
使用
-x
选项:通过在运行脚本时使用-x
选项,Bash 会在执行每一行命令之前打印该命令。这有助于查看脚本的执行流程和变量的值变化。例如,如果有一个名为
script.sh
的脚本,可以这样调用来启用调试模式:bash -x script.sh
-
设置
set
命令:在脚本内部,可以使用set
命令来开启或关闭调试模式。set -x
会打开调试模式,set +x
会关闭调试模式。例如:
# 开启调试模式 set -x # 一些要被调试的命令 echo "Debugging" # 关闭调试模式 set +x
-
使用
trap
命令:trap
命令可以在脚本执行时捕获信号,并执行指定的命令或函数。通过使用trap
和DEBUG
信号,可以在每个命令执行前执行特定的代码,帮助调试。例如,打印每个命令及其参数:
trap 'echo "Executing: $BASH_COMMAND"' DEBUG
-
逐步调试:Bash 的
-v
选项可以打印出脚本中的每一行命令,就像它们从脚本中读取出来一样,而不是执行后的结果。这有助于了解脚本的流程。通过命令行使用
-v
选项:bash -v script.sh
结合这些方法可以有效地调试 Bash 脚本,找出并修复错误。在复杂脚本的调试中,可能需要结合使用几种方法以更全面地理解脚本的行为。
2.简述如何在 Shell 脚本中传递参数?
在 Shell 脚本中传递参数可以使脚本更加灵活和动态。当执行一个脚本时,可以向其传递参数,这些参数在脚本内部可以通过特定的变量来访问。以下是如何在 Bash 脚本中传递和处理参数的基本方法:
-
使用位置参数:在脚本中,
$1
,$2
,$3
, ... 分别表示传递给脚本的第一个参数、第二个参数、第三个参数等。$0
是脚本名称本身。例如,如果有一个名为
script.sh
的脚本,可以这样传递参数:./script.sh param1 param2 param3
在脚本中,可以这样访问这些参数:
echo "第一个参数为:$1" echo "第二个参数为:$2"
-
使用
$#
来获取参数的数量:这个变量表示传递给脚本的参数总数。例如:
echo "参数总数为:$#"
-
使用
$*
和$@
来访问所有参数:$*
和$@
都代表所有传递给脚本的参数,但是在双引号中使用时有所不同。"$*"
将所有的参数看作一个单一的字符串,而"$@"
将每个参数都看作独立的字符串。例如:
for arg in "$*"; do echo "通过 \$* 遍历: $arg" done for arg in "$@"; do echo "通过 \$@ 遍历: $arg" done
-
使用
shift
命令来移动参数:shift
命令用于将位置参数向左移动。例如,shift 1
(默认值)将$2
的值赋给$1
,将$3
的值赋给$2
,以此类推,最初的$1
值被丢弃。这对于处理未知数量的参数特别有用:
while [ "$#" -gt 0 ]; do echo "处理参数:$1" shift done
通过这些方法,可以有效地在 Bash 脚本中传递和处理参数,使得脚本能够以更灵活的方式执行操作。
3.Shell 中exec跟source差在哪?
exec
和 source
是 Bash Shell 中两个功能强大且用途不同的命令,它们在脚本执行和环境管理方面发挥着不同的作用。
exec
命令
-
用途:
exec
命令用于替换当前的 shell 进程,而不是启动新的子进程。当使用exec
执行一个命令时,该命令会接管当前的进程(也就是当前的 shell 或脚本),并且当exec
执行的命令结束时,进程也就结束了,不会返回到原来的 shell 或脚本中。 -
示例:如果在一个脚本中执行
exec ls
,则ls
命令会在当前的进程中运行,执行完毕后,脚本就结束了,因为当前的进程已经被ls
命令替换。
source
命令
-
用途:
source
命令(在某些 shell 中用.
也可以表示)用于在当前 shell 环境中执行指定的脚本文件。与直接执行脚本(会启动一个新的子 shell 来运行)不同,source
命令会在当前的 shell 环境中读取并执行命令,这意味着脚本中的变量和函数等会直接影响当前的 shell 环境。 -
示例:如果你有一个设置环境变量的脚本
env.sh
,使用source env.sh
或. env.sh
执行后,脚本中定义的变量会在当前 shell 中可用。
主要差异
-
进程替换与环境影响:
exec
替换当前进程,而source
在当前 shell 环境中执行脚本,不创建新的进程。 -
用途:
exec
通常用于在脚本中改变当前进程的行为,例如,永久转到新的命令;source
用于执行脚本文件中的命令,并使脚本中定义的任何变量或更改直接影响当前的 shell 环境。 -
返回行为:使用
exec
执行命令后,当前 shell 或脚本不会继续执行后续的命令。使用source
执行脚本后,当前 shell 仍然活跃,可以继续执行其他命令。
了解这些差异有助于在编写脚本或管理系统时更有效地使用这些命令。
4.如何让 Shell 就脚本得到来自终端的输入?
在 Shell 脚本中获取来自终端的输入可以通过多种方式实现,这里介绍几种常用方法:
使用 read
命令
read
命令是 Bash 中用于从标准输入(默认为键盘输入)读取数据的最直接方法。当 read
命令执行时,它会暂停脚本的执行,等待用户输入,直到接收到换行符(通常是用户按下 Enter 键)。
基本用法:
echo "请输入您的名字:" read name echo "欢迎,$name!"
-
在这个例子中,脚本会输出提示信息,然后等待用户输入。用户输入的文本会被赋值给变量
name
,然后脚本会使用这个变量。
使用 read
的选项
read
命令还有一些有用的选项,例如:
-
-p
允许你直接在read
命令中指定提示信息。 -
-s
使得输入对用户不可见,这在读取密码时特别有用。
示例:
read -p "请输入您的用户名:" username read -sp "请输入您的密码:" password echo echo "用户名:$username,密码:$password"
从命令行参数获取输入
除了直接从终端读取输入,还可以通过脚本的命令行参数向脚本传递输入。这在执行脚本时已经知道所有必要信息的情况下特别有用。
示例:
# 使用方式: script.sh <name> echo "欢迎,$1!"
-
在这个例子中,
$1
是脚本接收的第一个命令行参数。
使用管道或重定向
你还可以通过管道(|
)或输入重定向(<
)来传递数据给 Shell 脚本,这允许你将其他命令的输出作为输入传递给脚本。
示例:
echo "John" | ./welcome_script.sh
-
这里假设
welcome_script.sh
脚本中使用了read name
来读取输入。
每种方法适用于不同的场景,可以根据具体需求和上下文选择最合适的一种。
5.简述什么是Shell函数 ?
Shell 函数是一种封装了一系列命令的代码块,可以在 Shell 脚本中定义并重复使用。这些函数类似于其他编程语言中的函数,使得代码更加模块化、易于管理和复用。在 Bash 脚本中定义和使用函数可以简化复杂的脚本,通过避免重复的代码来提高脚本的效率和可读性。
定义 Shell 函数
Shell 函数可以通过以下两种方式之一定义:
-
使用
function
关键字:function my_function { echo "这是一个 Shell 函数" }
-
直接使用函数名,不带
function
关键字:my_function() { echo "这是一个 Shell 函数" }
两种定义方式在功能上没有区别,可以根据个人偏好或团队规范选择使用。
调用 Shell 函数
定义函数后,可以通过简单地写出其名称来调用它,如下所示:
my_function
向函数传递参数
Shell 函数支持向其传递参数。在函数内部,可以通过 $1
, $2
, $3
, ... 来访问这些参数,就像处理脚本参数一样。
function greet { echo "Hello, $1!" } greet "World" # 输出 "Hello, World!"
函数的返回值
在 Shell 函数中,可以使用 return
命令来返回一个状态码(0 表示成功,非0 表示失败)。此外,函数可以通过标准输出来“返回”数据,这可以通过命令替换来捕获($(my_function)
)。
使用场景
Shell 函数在多种场景下非常有用,例如:
-
封装重复使用的代码块,提高脚本的可读性和可维护性。
-
定义处理特定任务的逻辑,使主脚本逻辑更清晰。
-
模块化复杂脚本,便于管理和调试。
总的来说,Shell 函数是 Bash 编程中一个非常强大的特性,它提供了一种简便的方法来组织和重用代码,有助于创建更加结构化和高效的脚本。
6.var=value? export前后差在哪?
在 Shell 脚本或命令行中设置变量时,可以选择使用 export
命令或不使用。export
命令的使用与否影响变量的可见性和作用域,特别是在当前 shell 环境与子进程之间的交互中。下面详细解释这两种情况的区别:
不使用 export
:
当你在 Shell 中定义一个变量时,如果不使用 export
,这个变量默认是局部的,只在当前 shell 环境中可见。这意味着你在当前的命令行会话或脚本中可以访问和修改这个变量,但它对子进程是不可见的。
示例:
var=value
如果你在这之后启动了一个子 shell 或者从这个 shell 环境中运行了一个脚本,那么这个子进程将无法访问 var
变量。
使用 export
:
export
命令可以改变这种情况。当你使用 export
将一个变量标记为"导出"时,这个变量不仅在当前 shell 环境中可见,也会被传递到由当前 shell 启动的任何子进程中。
示例:
export var=value
这样,如果你在设置了 export
的变量之后启动一个子 shell 或脚本,这个子进程可以访问 var
变量。
总结:
-
不使用
export
:变量只在定义它们的当前 shell 环境中可见。它们对任何从这个环境启动的子 shell 或子进程都是不可见的。 -
使用
export
:变量不仅在当前 shell 环境中可见,也对任何从这个环境启动的子 shell 或子进程可见。
使用 export
的主要场景包括设置环境变量或确保某些变量在多个相关的脚本或进程之间共享。理解这一点对于编写能够正确交互的 Shell 脚本和命令行程序非常重要。
7.Bash Shell 中 $! 表示什么意思 ?
在 Bash Shell 中,$!
表示最后一次在后台运行的进程的进程 ID (PID)。当你在命令行中使用 &
符号运行一个命令或者在脚本中启动一个后台进程时,Bash 会为该进程分配一个唯一的进程 ID。$!
就用于获取这个 ID,这在需要监控或操作特定后台进程的情况下非常有用。
示例
假设你在 Bash 中运行了一个后台进程,并且想要获取这个进程的 PID 来监控它的状态或等待它完成,可以这样做:
some_long_running_command & echo "后台进程的 PID 是 $!"
在这个例子中,some_long_running_command &
命令启动了一个后台进程。$!
将输出这个后台进程的 PID,你可以使用这个 PID 来执行诸如等待进程结束或检查进程状态的操作。
使用场景
-
监控后台进程:通过获取后台进程的 PID,你可以使用
ps
命令或其他工具来监控该进程的运行状态。 -
等待进程结束:如果你想在脚本中启动一个后台进程,并在该进程完成后立即执行某些操作,可以使用
wait $!
命令来实现。wait
命令会暂停脚本执行,直到指定的 PID 的进程结束。
$!
是 Bash 编程中一个非常有用的特性,尤其是在处理并发和后台处理任务时。通过合理利用 $!
,你可以更加灵活地控制脚本的执行流程,实现复杂的后台任务管理和协调。
8.解释Bash $* 和 $@ 有什么区别 ?
在 Bash Shell 脚本中,$*
和 $@
都是用来引用所有传递给脚本或函数的参数。尽管它们在很多情况下表面上看起来相似,但在特定的上下文中,特别是当它们被双引号包围时,它们的行为会有重要的区别。
$*
和 $@
的相似之处
-
在不被双引号包围时,
$*
和$@
都会将传递给脚本或函数的所有参数展开为一个单一的字符串,参数之间默认由空格分隔。
$*
和 $@
的区别
-
不带双引号时:没有明显的区别,它们都将参数作为一个整体展开,但是处理方式略有不同,通常这种差异在实际使用中不会有太大影响。
-
带双引号时:
-
"${*}"
:将所有的参数看作一个整体,合并成一个单一的字符串,参数之间用第一个空白字符(通常是空格)分隔。 -
"${@}"
:将每个参数看作独立的引用字符串,保留每个参数的边界。这在处理包含空格或特殊字符的参数时非常有用。
-
示例
假设一个脚本被这样调用:./script.sh "arg1" "arg2 with spaces" "arg3"
-
使用
$*
或$@
不带双引号时,它们的行为相同,都会将参数展开为:arg1 arg2 with spaces arg3
-
使用
"${*}"
时,它会将所有参数视为一个整体,结果是:"arg1 arg2 with spaces arg3"
-
使用
"${@}"
时,它会保留每个参数的独立性,适合遍历所有参数,结果是像这样分开处理每个参数:-
"arg1"
-
"arg2 with spaces"
-
"arg3"
-
使用场景
-
当你需要将所有参数作为一个整体处理时,使用
"${*}"
。 -
当你需要分别处理每个参数,尤其是参数中包含空格或需要精确控制每个参数时,使用
"${@}"
。
了解这两者之间的区别对于编写更健壮、更灵活的 Bash 脚本至关重要,尤其是在处理复杂的参数和输入数据时。
9.查找某个路径下的所有包含某个特定字符串的文件(递归查找)?
要在某个路径下递归查找所有包含特定字符串的文件,可以使用 grep
命令结合一些选项进行操作。grep
是一种强大的文本搜索工具,可以在文件中搜索匹配指定模式的字符串。当与递归搜索选项结合使用时,grep
能够在指定目录及其所有子目录中搜索文件内容。
使用 grep
进行递归查找
以下是使用 grep
查找包含特定字符串的文件的基本命令:
grep -r "特定字符串" /path/to/directory
-
-r
或--recursive
选项告诉grep
递归地查找指定目录下的所有文件。 -
"特定字符串"
是你想要搜索的文本。 -
/path/to/directory
是你想要开始搜索的目录路径。
其他有用的选项
-
-i
:忽略大小写。 -
-l
:仅列出包含匹配项的文件名,而不显示匹配行的具体内容。 -
-n
:显示匹配行及其行号。
示例
假设你想要在 /home/user/docs
目录及其子目录中查找包含字符串 "example" 的所有文件,忽略大小写,并且只想列出包含该字符串的文件名:
grep -ril "example" /home/user/docs
这个命令将会递归地搜索 /home/user/docs
目录,找到所有文件内容中包含 "example"(不区分大小写)的文件,并且只列出这些文件的路径。
使用 grep
进行递归搜索是在命令行环境下快速找到包含特定内容的文件的有效方法。
10.写一个脚本实现判断192.168.1.0/24网络里,当前在线的IP有哪些,能ping通则认为在线 ?
要实现这个功能,我们可以编写一个简单的 Bash 脚本,使用 ping
命令逐个检查指定网络中的 IP 地址是否在线。以下是一个基本的脚本示例,它遍历 192.168.1.0/24 网络中的每个 IP 地址(从 192.168.1.1 到 192.168.1.254),使用 ping
命令发送少量的 ICMP Echo 请求以判断主机是否在线。
#!/bin/bash # 网络的基础部分 base_ip="192.168.1" # 循环遍历 1 到 254 的每个可能的主机号 for i in {1..254}; do # 构造完整的 IP 地址 ip="$base_ip.$i" # 使用 ping 命令检查 IP 地址 # -c 1 表示发送一个 ICMP Echo 请求 # -W 1 表示等待回应的最大时间(秒) ping -c 1 -W 1 $ip &> /dev/null # 检查 ping 命令的退出状态 if [ $? -eq 0 ]; then echo "IP 地址 $ip 在线" fi done
这个脚本的工作流程如下:
-
定义了网络的基础 IP 部分(
base_ip
)。 -
使用
for
循环遍历网络中的每个主机号(从 1 到 254)。 -
对于循环中的每个数字,构造完整的 IP 地址,并使用
ping
命令尝试向该地址发送 ICMP Echo 请求。 -
ping
命令的选项-c 1
指定发送请求数量为 1,-W 1
设置等待回应的最大时间为 1 秒。这样做是为了加快脚本的执行速度。 -
通过检查
ping
命令的退出状态($?
),判断主机是否在线。如果退出状态为 0(表示成功),则认为该 IP 地址在线,并打印相应的消息。
请注意,这个脚本可能需要管理员权限(或使用 sudo
)来运行,因为 ping
命令在某些系统上可能需要这些权限。此外,这种方法可能不会检测到配置为不响应 ICMP Echo 请求的主机。
11.Shell 添加一个新组为class1,添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01 到30 ?
要实现这个需求,你可以编写一个 Shell 脚本来首先创建一个名为 class1
的新组,然后循环添加用户名为 std01
到 std30
的用户,并将这些用户分配到 class1
组。下面是一个简单的脚本示例,演示了如何执行这些操作:
#!/bin/bash # 创建新组 class1 groupadd class1 # 循环添加用户 std01 到 std30 for i in $(seq -w 1 30); do user="std$i" # 添加用户,并将其加入到 class1 组 useradd -m -g class1 "$user" echo "用户 $user 已创建并添加到组 class1。" done echo "所有用户已成功创建并添加到组 class1。"
这个脚本的关键点如下:
-
使用
groupadd class1
命令创建一个新组class1
。 -
使用
seq -w 1 30
生成从 01 到 30 的数字序列。-w
选项确保序列中的数字被格式化为两位数,即01
,02
, ...,30
。 -
对于序列中的每个数字,构造用户名
stdXX
,其中XX
是当前的数字。 -
使用
useradd -m -g class1 "$user"
命令添加用户。-m
选项表示创建用户的主目录,-g class1
选项表示将用户添加到class1
组。 -
打印一条消息确认用户已被创建并添加到组。
在运行这个脚本之前,请确保你有足够的权限来创建用户和组。在大多数系统上,这意味着你需要以 root 用户身份执行该脚本,或使用 sudo
命令。
请注意,根据你的系统配置和已存在的用户/组设置,这个脚本可能需要进行适当的调整。例如,如果 class1
组已经存在,groupadd class1
命令将会失败,你可能需要检查组是否存在,然后决定是否需要执行添加组的命令。
12.某系统管理员需每天做一定的重复工作,请按照下列要求,编制一个解决方案?
要自动化和优化系统管理员的重复工作,我们可以利用 Linux 系统中的 cron
作业来安排这些任务定时执行。不过,我将提供一个稍微不同的角度来解决这个问题,增加一些解释和改进,使解决方案更加健壮和灵活。
1. 创建 cron
作业
首先,我们将编写一个 cron
文件来定义所有定时任务。我们可以直接编辑 crontab
,而不是首先创建一个外部文件。这样可以确保 crontab
的内容始终与系统的 cron
守护进程同步。
打开终端并输入以下命令编辑当前用户的 crontab
文件(如果需要以超级用户权限执行,可以在命令前加 sudo
):
crontab -e
然后,在打开的编辑器中添加以下内容:
# 每天16:50清理 /abc 目录下的所有文件和文件夹 50 16 * * * rm -rf /abc/* # 每小时备份 /xyz/x1 文件的第一列到 /backup/bak01.txt,从早上8点到晚上18点,每小时执行一次 0 8-18 * * * cut -f1 /xyz/x1 >> /backup/bak01.txt # 每天17:50对 /data 目录进行压缩备份 50 17 * * * tar zcvf /path/to/backup/backup.tar.gz /data # 每天17:55卸载 /dev/hdc 55 17 * * * umount /dev/hdc
2. 解释和改进
-
使用
crontab -e
直接编辑:这样做的好处是可以避免权限问题,且cron
服务会自动加载新的配置,无需手动加载。 -
路径注意事项:在
cron
作业中使用全路径(例如,使用/usr/bin/cut
而不是cut
),因为cron
的环境变量可能与你的交互式 shell 环境不同。 -
日志记录:对于每个任务,特别是可能失败的任务(如
umount
),考虑添加日志记录,例如:umount /dev/hdc >> /var/log/umount.log 2>&1
,以便于问题追踪。 -
错误处理:为了确保任务的健壮性,可以在命令中添加一些错误处理逻辑,或者使用脚本包装复杂的命令,并在脚本中进行错误检查。
3. 自动启动 cron
服务
确保 cron
服务在系统启动时自动运行是很重要的。大多数现代 Linux 发行版默认会启动 cron
服务,但你可以使用以下命令检查和启用 cron
服务(以 systemd 为例):
# 检查cron服务状态 systemctl status cron # 如果没有运行,则启动cron服务 sudo systemctl start cron # 设置cron服务在系统启动时自动运行 sudo systemctl enable cron
通过这种方式,我们不仅自动化了重复的日常任务,还增加了日志记录和错误处理,提高了维护性和可靠性。
13.描述Linux shell中单引号、双引号及不加引号的简单区别
在 Linux Shell 中,单引号、双引号以及不加引号用于处理字符串和命令参数时有着重要的区别,这些区别影响着变量的展开、命令的执行以及字符串的解释。下面是对这些区别的简单描述:
不加引号
-
不加引号时,Shell 会根据空格、制表符等空白字符将输入分割成多个单词或参数。此外,特殊字符(如
*
、?
、$
等)会按照 Shell 的规则(如路径扩展、变量替换、命令替换等)进行处理。 -
示例:在表达式
echo $HOME
中,$HOME
会被替换成当前用户的主目录路径。
单引号 ' '
-
单引号内的任何字符都会被视为普通字符,包括 Shell 特殊字符(如
$
、"
、\
等)。Shell 不会对单引号内的内容进行变量替换、命令替换或任何其他特殊处理。 -
示例:
echo '$HOME'
会原样输出字符串$HOME
,而不是用户的主目录路径。
双引号 " "
-
双引号内的文本大部分被视为普通字符,但 Shell 仍然会对某些特殊字符(如
$
、`
(反引号,用于命令替换)、\
(当其后跟特殊字符时))进行特殊处理,比如变量替换和命令替换。 -
示例:
echo "$HOME"
会输出当前用户的主目录路径。但是,echo "This is a dollar sign: \$"
中的$
被转义了,因此它会被视为普通字符,输出结果为This is a dollar sign: $
。
总结
-
不加引号:适合需要 Shell 特殊字符扩展的场合。
-
单引号:适合完全按字面意义处理字符串的场合,不需要任何变量或命令替换。
-
双引号:适合需要部分特殊处理(如变量替换)但又要避免字符串被空白字符分割或是需要防止大部分特殊字符被当作特殊操作的场合。
正确地使用引号对于编写有效的 Shell 脚本和正确地执行命令至关重要。
14.编写Shell脚本获取本机网络地址 如:本机的IP是:192.168.100.2/255.255.255.0,那么它的网络地址是 ?
获取本机网络地址的 Shell 脚本可以通过提取 IP 地址和子网掩码,然后计算得出网络地址。以下是一个基本的脚本示例,它利用 ip
命令获取 IP 地址和子网掩码,并使用 awk
和 ipcalc
工具进行计算以得出网络地址。
首先,确保你的系统上安装了 ipcalc
。在某些 Linux 发行版中,ipcalc
可能不是预安装的,可以通过包管理器安装,如使用 apt
(Debian/Ubuntu)或 yum
(CentOS/RHEL):
sudo apt-get install ipcalc # Debian/Ubuntu sudo yum install ipcalc # CentOS/RHEL
然后,你可以编写如下脚本:
#!/bin/bash # 获取默认网络接口 interface=$(ip route show default | awk '/default/ {print $5}') # 获取该接口的IP地址和子网掩码 ip_and_mask=$(ip addr show $interface | awk '/inet / {print $2}') # 使用ipcalc获取网络地址 network=$(ipcalc $ip_and_mask | grep Network | awk '{print $2}') echo "本机的网络地址是:$network"
这个脚本的工作流程如下:
-
使用
ip route show default
命令找到默认网络接口。 -
利用
ip addr show
命令和awk
工具从默认接口中提取 IP 地址和子网掩码。 -
使用
ipcalc
工具和grep
命令从ipcalc
的输出中提取网络地址。 -
输出网络地址。
请注意,这个脚本假设你的系统有一个主要的网络接口用于连接网络,且 ipcalc
命令可以正常运行。在一些特定配置或多接口系统中,可能需要调整这个脚本以适应具体的网络设置。
15.添加一个新组为 class1 ,然后添加属于这个组的 30 个用户,用户名的形式为 stdxx ,其中 xx 从 01 到 30 ?
为了添加一个新组 class1
并在该组下添加 30 个用户(用户名形式为 std01
到 std30
),你可以执行以下 Shell 命令:
groupadd class1 useradd -m -g class1 std01 useradd -m -g class1 std02 useradd -m -g class1 std03 useradd -m -g class1 std04 useradd -m -g class1 std05 useradd -m -g class1 std06 useradd -m -g class1 std07 useradd -m -g class1 std08 useradd -m -g class1 std09 useradd -m -g class1 std10 useradd -m -g class1 std11 useradd -m -g class1 std12 useradd -m -g class1 std13 useradd -m -g class1 std14 useradd -m -g class1 std15 useradd -m -g class1 std16 useradd -m -g class1 std17 useradd -m -g class1 std18 useradd -m -g class1 std19 useradd -m -g class1 std20 useradd -m -g class1 std21 useradd -m -g class1 std22 useradd -m -g class1 std23 useradd -m -g class1 std24 useradd -m -g class1 std25 useradd -m -g class1 std26 useradd -m -g class1 std27 useradd -m -g class1 std28 useradd -m -g class1 std29 useradd -m -g class1 std30
这组命令首先创建了一个名为 class1
的新用户组,然后逐个添加用户 std01
到 std30
,并将这些用户指定到 class1
组。这里的 -m
选项用于创建用户的主目录,-g
选项指定用户的初始登录组。请以 root 用户执行这些命令,或在命令前使用 sudo
来获取必要的权限。
由于内容太多,更多内容以链接形势给大家,点击进去就是答案了
16. 写一个 sed 命令,修改 /tmp/input.txt 文件的内容?
17. 编写个 shell 脚本将/usr/local/test 目录下大于 100K 的文件转移到/tmp 目录下 ?
20. 编写个shell脚本将当前目录下大于10K的文件转移到/tmp目录下 ?
21. 编写Shell显示file.txt的1,3,5,7,10,15行?
23. 编写Shell找出系统内大于50k,小于100k的文件,并删除它们 ?
27. 命令: name=John && echo 'My name is $name' 的输出是什么 ?
28. 如何使用 awk 列出 UID 小于 100 的用户 ?
29. ${variable:-10} 和 ${variable: -10} 有什么区别?
30. "export $variable" 或 "export variable" 哪个正确 ?
33. Shell 写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令 ?
34. 简述[ $a == $b ] 和 [ $a -eq $b ] 有什么区别 ?
[35. 简述 [[ $string == abc* ]] 和 [[ $string == "abc*" ]] 有什么区别 ?](简述 [[ $string == abc\* \]] 和 [[ $string == “abc\*” ]] 有什么区别 ?-帅地玩编程)
36. Shell脚本如何实现监控iptables运行状态 ?