某些情况下,用户可能会连续的进行某些指令的下达。 但这些指令之间可能会有关连性,例如前一个指令成功后才可进行下一个指令等。 这些情况就需要使用到特殊的字符来处理。
前面的章节我们一直使用到bash终端环境下的指令操作,而且一直接触到很多的单引号、双引号、钱字号、反单引号、大括号、小括号等等,其实在该成对的符号内,隐藏了:指令、变量、计算式等的功能! 再次了解特殊的符号的用途,请完成底下的练习:
var=${ }
var=$( )
var=$(( ))
var=" "
var=' '
var=` `
接下来,直接应用一下上面的功能:
先以 which command 的方式找出指令的全名
将上述的结果,使用 ls -l 显示出来。 请搭配前一个例题的符号 ($, ', ", ' 等) 来处理。
指令的执行正确与否与后续的处理有关。 Linux 环境下默认的指令正常结束回传值为 0 ,呼叫的方式为使用' echo $? 』 即可, 亦即找出 ? 这个变数的内容即可。
输入『 /etc/passwd 』这个文件名在指令列,之后再输入『 echo $? 』 观察输出的号码为何?
输入『 vbirdcommand 』这个指令名,之后再输入『 echo $? 』 观察输出的号码为何?
因为尚未进入其他指令(上述两个文件名、指令都是不正确的),因此这些错误讯息应该来自于bash本身的判断。 因此使用' man bash '后,查询『 ^exit status '关键词,找出上述号码的意义为何?
承上,该段文字叙述中,解释的回传值共有几个号码?
输入『 ls /vbird ',之后观察输出的回传值,查询该回传值的意义为何? (你应该要 man ls 还是 man bash 呢? )
上述的练习在让用户了解到,指令回传值是每个指令自己指定的,只要符合 bash 的基本规范即可。
命令是可以连续输入的,直接通过分号(;) 隔开每个指令即可。 在没有依赖的命令环境中,可以直接进行如下的行为:
列出目前的日期,直接使用 date 即可;
使用 uptime 列出当前系统信息;
列出核心信息;
[student@localhost ~]$ date; uptime; uname -r日 4月 19 15:22:43 CST 2020 15:22:43 up 48 min, 2 users, load average: 0.00, 0.00, 0.00 4.18.0-147.el8.x86_64
如此一口气就可以直接将所有的指令执行完毕,无须考量其他问题。 当用户有多个指令需要下达,每个指令又需要比较长的等待时间时, 可以使用这种方式来处理即可。 但是,如果想要将这些信息同步输出到同一个档案时,应该如何处理? 参考底下两个范例后,说明其差异为何?
请使用底下的两个指令处理数据流,探讨其原因
[student@localhost ~]$ date; uptime; uname -r > myfile.txt[student@localhost ~]$ (date; uptime; uname -r ) > myfile.txt
具有指令相依性的 && ||
分号 (;) 是直接连续下达指令,指令间不必有一定程度的相依性。 但当指令之间有相依性时,就能够使用 && 或 || 来处理。 这两个处理的方式如下:
command1 && command2
当 command1 执行回传为 0 时(成功),command2 才会执行,否则就不执行。
command1 || command2
当 command1 执行回传为非 0 时(失败),command2 才会执行,否则就不执行。
[student@localhost ~]$ ls -ld /dev/shm/checkls: 無法存取 '/dev/shm/check': 沒有此一檔案或目錄# 確認該檔名是不存在的![student@localhost ~]$ ls -ld /dev/shm/check || mkdir /dev/shm/checkls: 無法存取 '/dev/shm/check': 沒有此一檔案或目錄 [student@localhost ~]$ ls -ld /dev/shm/checkdrwxrwxr-x. 2 student student 40 4月 19 16:26 /dev/shm/check# 檔案出現了!這是因為 mkdir 的緣故![student@localhost ~]$ ls -ld /dev/shm/check || mkdir /dev/shm/checkdrwxrwxr-x. 2 student student 40 4月 19 16:26 /dev/shm/check# 再次運作也不會出現 mkdir 的錯誤! || 會略過正確訊息的動作!
[student@localhost ~]$ ls -ld /dev/shm/check && rmdir /dev/shm/checkdrwxrwxr-x. 2 student student 40 4月 19 16:26 /dev/shm/check# 兩個指令都分別順利運作完畢[student@localhost ~]$ ls -ld /dev/shm/check && rmdir /dev/shm/checkls: 無法存取 '/dev/shm/check': 沒有此一檔案或目錄# 第一個 ls 的指令失敗,因此並沒有執行 rmdir 喔!若不信,使用底下指令看看:[student@localhost ~]$ ls -ld /dev/shm/check ; rmdir /dev/shm/checkls: 無法存取 '/dev/shm/check': 沒有此一檔案或目錄 rmdir: failed to remove '/dev/shm/check': 沒有此一檔案或目錄
假设我们需要一个指令来说明某个文件名是否存在,可以这样处理:
[student@localhost ~]$ ls -d /etc && echo exist || echo non-exist/etc exist [student@localhost ~]$ ls -d /vbird && echo exist || echo non-existls: 無法存取 /vbird: 沒有此一檔案或目錄 non-exist
由于我们只是想要知道该档案是否存在,因此不需要如上表所示,连 ls 的结果也输出。 此时可以使用 &> 的方式来将结果输出到垃圾桶,如下所示:
[student@localhost ~]$ ls -d /etc &> /dev/null && echo exist || echo non-existexist [student@localhost ~]$ ls -d /vbird &> /dev/null && echo exist || echo non-existnon-exist
尝试自行撰写小程序
由于上述指令要修改很麻烦,假设我们需要使用' checkfile filename '来处理,此时可以撰写一只小脚本来进行此任务。 若该指令可以让所有用户执行,则可将指令写入 /usr/local/bin 目录内。
[root@localhost ~]# vim /usr/local/bin/checkfile#!/bin/bash ls -d ${1} &> /dev/null && echo "${1} exist" || echo "${1} non-exist"[root@localhost ~]# chmod a+x /usr/local/bin/checkfile[root@localhost ~]# checkfile /etc/etc exist [root@localhost ~]# checkfile /vbird/vbird non-exist
在 checkfile 文件中,第一行 (#!/bin/bash) 代表使用 bash 来执行底下的语法,第二行当中的变量 ${1} 代表在本档案后面所接的第一个参数,因此执行时,就能够直接将要判断的文件名接在 checkfile 后面即可。
事实上,前一小节使用 ls 进行确认文件名时,仅需要确认回传值是否为 0 而已。 Linux 提供一个名为 test 的命令可以确认许多文件名参数, 常见的参数有:
测试的标志 | 代表意义 |
1. 关于某个文件名的'文件类型'判断,如 test -e filename 表示存在否 | |
-e | 该'文件名'是否存在? (常用) |
-f | 该'文件名'是否存在且为档案(file)? (常用) |
-d | 该'文件名'是否存在且为目录(directory)? (常用) |
-b | 该'文件名'是否存在且为一个 block device 装置? |
-c | 该'文件名'是否存在且为一个 character device 装置? |
-S | 该'文件名'是否存在且为一个 Socket 档案? |
-p | 该'文件名'是否存在且为一个 FIFO (pipe) 文件? |
-L | 该'文件名'是否存在且为一个链接文件? |
2. 关于文件的权限检测,如 test -r filename 表示可读否 (但 root 权限常有例外) | |
-r | 侦测该文件名是否存在且具有'可读'的权限? |
-w | 侦测该文件名是否存在且具有'可写'的权限? |
-x | 侦测该文件名是否存在且具有'可执行'的权限? |
-u | 侦测该文件名是否存在且具有'SUID'的属性? |
-g | 侦测该文件名是否存在且具有'SGID'的属性? |
-k | 侦测该文件名是否存在且具有'Sticky bit'的属性? |
-s | 侦测该文件名是否存在且为'非空白档案'? |
3. 两个文件之间的比较,如: test file1 -nt file2 | |
-nt | (newer than)判断 file1 是否比 file2 新 |
-ot | (older than)判断 file1 是否比 file2 旧 |
-ef | 判断 file1 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要意义在判定,两个档案是否均指向同一个 inode 哩! |
4. 关于两个整数之间的判定,例如test n1 -eq n2 | |
-eq | 两数值相等(equal) |
-ne | 两数值不等(not equal) |
-gt | n1 大於 n2 (greater than) |
-lt | n1 小於 n2 (less than) |
-ge | n1 大于等于 n2 (greater than or equal) |
-le | n1 小於等于 n2 (less than or equal) |
5. 判定字符串的数据 | |
test -z string | 判定字符串是否为 0 ? 若 string 为空字串,则为 true |
test -n string | 判定字符串是否非为 0 ? 若 string 为空字串,则为 false。 注: -n 亦可省略 |
test str1 == str2 | 判定 str1 是否等于 str2 ,若相等,则回传 true |
test str1 != str2 | 判定 str1 是否不等于 str2 ,若相等,则回传 false |
6. 多重条件判定,例如: test -r filename -a -x filename | |
-a | (and)两状况同时成立! 例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。 |
-o | (or)两状况任何一个成立! 例如test-rfile-o-x file,则file具有rax权限时,就可回传true。 |
! | 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true |
test 仅会回传 $? 而已,屏幕上不会出现任何的变化,因此如果需要取得回应,就需要使用 echo $? 的方式来查询, 或者使用 && 及 || 来处理。
使用 test 判断 /etc/ 是否存在,然后显示回传值
使用 test 判断 /usr/bin/passwd 是否具有 SUID ,然后显示回传值
使用 test 判断 ${HOSTNAME} 是否等于 "mylocalhost" ,然后显示回传值
修改 /usr/local/bin/checkfile ,取消 ls 的判断,改用 test 判断
使用中括号 [] 取代 test 进行判别式的处理
由于 test 是直接加在变量判断之前,读者可能偶而会觉得怪异。 此时可以使用中括号 [] 来取代 test 的语法。 同样以 checkfile 来处理时,该文件的内容应该需要改写成如下:
[root@localhost ~]# vim /usr/local/bin/checkfile#!/bin/bash[ -e "${1}" ] && echo "${1} exist" || echo "${1} non-exist"
由于中括号的意义非常多,包括第三堂课万用字符当中,中括号代表的是'具有一个指定的任意字符',未来第九堂课的正规表示法当中, 中括号也具有特殊的字符意义。 而分辨是否为'判别式'的部份,就是其语法的差别。 请注意,在 bash 环境下,使用中括号替代 test 指令时, 中括号的内部需要留白一个以上的空白字符! 如下图标:
[ "$HOME" == "$MAIL" ] [□"$HOME"□==□"$MAIL"□] ↑ ↑ ↑ ↑
使用 [ ] 判断 /etc/ 是否存在,然后显示回传值
使用 [ ] 判断 /usr/bin/passwd 是否具有 SUID ,然后显示回传值
使用 [ ] 判断 ${HOSTNAME} 是否等于 "mylocalhost" ,然后显示回传值
自定义回传值意义
如果用户想要使用简易的 shell script 创立一个指令,也能够自己设定回传值的意义。
[root@localhost ~]# vim /usr/local/bin/myls.sh#!/bin/bash ls ${@} && exit 100 || exit 10[root@localhost ~]# chmod a+x /usr/local/bin/myls.sh[student@localhost ~]$ myls.sh /vbird; echo $?ls: 無法存取 '/vbird': 沒有此一檔案或目錄10
上述的 ${@} 代表指令后面接的任何参数,因此你可以执行 myls.sh 后面接多个参数都没问题。 由于 exit 可以回传讯息,因此可以让用户简易的设置好所需要的回传讯息规范。
第一堂课开始读者应该就接到到 ls 与 ll 这两个指令,刚开始介绍时,读者们应该知道 ll 是 long list 的缩写。 若将 ll 这个指令用来取代 checkfile 这个脚本,是否可以处理?
[root@localhost ~]# vim /usr/local/bin/checkfile#!/bin/bash #[ -e "${1}" ] && echo "${1} exist" || echo "${1} non-exist"ll -d ${1} && echo "${1} exist" || echo "${1} non-exist"[root@localhost ~]# checkfile /etc/usr/local/bin/checkfile: 列 5: ll:命令找不到 /etc non-exist
但是,当你执行 checkfile /etc 时,竟然出现 command not found 的问题! 这是为什么? 因为系统上真的没有 ll 这个指令, 该指令为使用命令别名暂时创造出来的一个命令的别称 (别名) 而已。 若你在 root 的身份输入 alias 与在 student 的身份输入 alias, 那就会得到两个不同身份的命令别名了:
[root@localhost ~]# aliasalias cp='cp -i' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l.='ls -d .* --color=auto' alias ll='ls -l --color=auto' <==指令別名!alias ls='ls --color=auto' alias mv='mv -i' alias rm='rm -i' ...... [student@localhost ~]$ aliasalias cp='cp -i' alias egrep='egrep --color=auto' alias fgrep='fgrep --color=auto' alias grep='grep --color=auto' alias l.='ls -d .* --color=auto' alias ll='ls -l --color=auto' alias ls='ls --color=auto' alias mv='mv -i' alias rm='rm -i' alias vi='vim' <==跟 root 比,多出來的!......
因此读者应该能知道为何 /bin/ls -d /etc 与 ls -d /etc 输出的结果会有颜色差异的问题了。 此外,管理员执行 mv, cp, rm 等管理文件的指令时, 为了避免不小心导致的文件覆盖等问题,于是仅有 root 的身份会加上 -i 的选项,提示管理员相关的档案覆盖问题。 同时,管理员的 vi 与 vim 默认是不同的软件~一般帐号的 vi 与 vim 则通通是 vim 啊!
使用 root 的身份切换路径到 /dev/shm 底下,并将 /etc 整个目录复制到 '本目录'底下
若将上述指令重新执行一次,会发生什么问题?
如果您确定文件名就是需要覆盖,那可以使用什么方式来处理 (思考 A. 使用绝对路径不要用命令别名 B. 让指令自动忽略命令别名)
让指令不以命令别名的方式执行是相当值得注意的喔! 很有趣!
由于我们的 student 帐号也算管理员常用的帐号,因此建议也将 cp, mv, rm 默认加上 -i 的选项。 请问如何处理?
某些时刻管理器可能需要进行一串指令后,再将这串指令进行数据的处理,而非每个指令独自运作。 如下行命令的帮助:
[student@localhost ~]$ date; cal -3; echo "The following is log"[student@localhost ~]$ date; cal -3; echo "The following is log" > mylog.txt[student@localhost ~]$ cat mylog.txt
读者会发现到,原本想要纪录的信息当中,仅有最后一个指令才可以被处理了。 若需要每个指令都进行纪录,依据前面的介绍,则必须要如此处理:
[student@localhost ~]$ date > mylog.txt; cal -3 >> mylog.txt; echo "The following is log" >> mylog.txt
指令会变得相当复杂。 此时,可以通过数据统整的方式,亦即将所有的指令包含在小括号内,就能够将讯息统一输出了。
[student@localhost ~]$ (date; cal -3; echo "The following is log") > mylog.txt
设定一个命令别名为 geterr,内容为执行 echo "I am error" 1>&2
执行 geterr 得到什么结果?
执行 geterr 2> /dev/null 得到什么结果?
执行 (geterr) 2> /dev/null 得到什么结果?
尝试解析为何会这样?
某些时刻用户可能需要将屏幕的信息转存成为档案以方便纪录,就是前几堂课就已经谈到过得>这个符号的功能。 事实上,这个功能就是数据流重导向。
从前一小节的说明,读者可以知道指令执行后,至少可以输出正确与错误的数据 ($? 是否为 0), 某些指令执行时,则会从文件取得数据来处理,例如 cat, more, less 等指令。 因此,将命令对于数据的装入和输出汇整如下图:
standard output 与 standard error output
简单的说,标准输出指的是'指令执行所回传的正确的讯息',而标准错误输出可理解为' 指令执行失败后,所回传的错误讯息'。 不管正确或错误的数据都是默认输出到屏幕上,我们可以通过特殊的字符来进行数据的重新导向!
标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
以 student 身份执行找档名的任务,指令为『 find /etc -name '*passwd*' ',屏幕输出什么信息? 请了解 * 的意义。
student 对于系统配置文件原本就有很多的无权限目录,因此请将错误讯息直接丢弃 ( 导向于 /dev/null )
将最终屏幕的输出转存成为 ~student/find_passwd.txt 文件
再以 student 的身份重新搜寻 /etc 底下文件名为 *shadow* 的数据,将正确消息'累加'到 ~student/find_passwd.txt 档案内
查看 ~student/find_passwd.txt 文件内是否同时具有 passwd 与 shadow 相关的文件名存在?
上述的例题练习完毕后,可以将特殊的字符归类成:
1> :以覆盖的方法将'正确的数据'输出到指定的文件或设备上;
1>>:以累加的方法将'正确的数据'输出到指定的文件或设备上;
2> :以覆盖的方法将'错误的数据'输出到指定的文件或设备上;
2>>:以累加的方法将'错误的数据'输出到指定的文件或设备上;
一般来说,文件无法让两个程序同时打开还同时进行读写! 因为这样数据内容会反复的被改写掉,所以你不应该使用如下的方式来下达指令:
command > file.txt 2> file.txt
如果你需要将正确数据和错误数据同步写入同一个文件内,那就应该要这样思考:
将错误数据转到正确数据的管线上,然后同步输出
将正确数据转到错误数据的管线上,然后同步输出
全部数据通通按序同步输出( 无效和错误)
若同样使用' find /etc -name '*passwd*' '这个指令来处理,则读者可以尝试使用底下的方案来执行上述三个数据转管道的动作:
[student@localhost ~]$ find /etc -name '*passwd*' > ~/find_passwd2.txt 2>&1[student@localhost ~]$ find /etc -name '*passwd*' 2> ~/find_passwd2.txt 1>&2[student@localhost ~]$ find /etc -name '*passwd*' &> ~/find_passwd2.txt
但请注意指令的输入顺序, 2>&1 与 1>&2 必须要在指令的后面输入才行。
standard input
有些指令在执行时,你需要敲击键盘才行,这个 standard input 就可以由档案内容来取代键盘输入的意思。 举例来说,cat这个指令就是直接让你敲击键盘来由屏幕输出信息。
直接用 student 身份执行' cat '这个指令,然后随意输入两串文字,查阅指令执行的结果为何?
要结束指令的输入请执行 [ctrl]+d 结束 (并不是 [ctrl]+c 喔! )
若输入的字符串可以直接转存成为 mycat.txt 文件,该如何下达指令?
将 /etc/hosts 通过 cat 读入 (使用两种方式,直接读入与通过 < 方式读入)
将 /etc/hosts 通过 cat 以 < 的方式读入后,累加输出到 mycat.txt 文件内
上面的例题中,我们可以透过 [ctrl]+d 的方式来结束输入,但是一般用户可能会看不懂 [ctrl]+d 代表的意义是什么。 如果能够使用 end 或 eof 等特殊关键词来结束输入,那似乎更为人性化一些。 你可以使用下面的指令来处理:
[student@localhost ~]$ cat > yourtype.txt << eof> here is GoGo! > eof
最后一行一定要完整的输入 eof (上面的范例),这样就能够结束 cat 的输入,这就是 << 的意义~
读者在前几堂课曾经看过类似' ll /etc | more 』的指令,较特别的是管线 (pipe, |) 的功能。 管线的意思是, 将前一个指令的标准输出作为下一个指令的标准输入来处理! 流程有点像底下这样的图标:
另外,这个管道命令' | ' 仅能处理经由前面一个指令传来的正确信息,也就是 standard output 的信息,对于 stdandard error 并没有直接处理的能力。 如果你需要处理 standard error output ,就得要搭配 2>&1 这种方式来处理才行了。
管线仅会处理 standard output,对于 standard error output 会予以忽略
管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。
常见的管道命令有:
cut :裁切资料,包括通过固定符号或者是固定字符位置
grep :撷取特殊关键词的功能
awk '{print $N}' :以空白为间隔,印出第 N 个字段的项目
sort :进行资料排序
wc :计算数据的行数、字数、字符数
uniq :数据依行为单位,进行重复数据的计算
tee :将数据转存一份到文件中
split :将数据依据行数或容量数切割成数份
找出文件名最好使用 find 来处理,因此请使用 find /etc 来查看一下资料
你可以透过' find /etc -name '*.conf' '或' find /etc | grep '\.conf' 』来找到所需要的文件名。 由于grep可以加上颜色显示,故建议可以尝试使用grep的方式来显示较佳。
最终计算档案数,就可以使用 wc 这个指令来处理' find /etc | grep '\.conf' | wc -l 』
建议用户可以 man wc 看一下该指令的选项功能喔!
在 /etc/passwd 里面的第一栏位为账号名称,第七字段为 shell ,我想要只找这两个项目来输出,该如何处理?
承上,若我只想要知道有多少个 shell (第七字段),同时每个 shell 各有几个,又可以如何处理?
使用 last 可以查看到每个用户的登录情况,请通过 cut 取出第一个字段后,分析每个帐号的登录次数为何
使用 ip addr show 可以查询到每个网络界面的 IP 地址,若只想要取出 IPv4 的地址,应该如何处理?
承上,若只想要列出 IP 地址 (127.0.0.1/8 之类的),是否可以通过 awk 来达成?
承上,将取得的 IP 地址除了显示在屏幕上,亦同步输出到 /dev/shm/myip.txt 文件中。
上课的课后练习,非作业:
简单的操作底下的题目练习:
21世纪从2000到2099年,这100年当中,每四年有一次闰年,因此有1/4亦即25年有闰年(366天)。 请用 bash 的整数运算功能,直接算出这 100 年共有几天?
执行这串指令:『 bash -c "ls /check &> /dev/null && exit 10 || exit 20" 』, 回传值应该是多少?
设计一个指令,命令名称为 mykver,当执行后,屏幕会输出类似' My hostname is 'localhost' and kernel version is '4.xxx' ' 这样的字样。
纪录执行文件的指纹资料,请使用 md5sum 将 /usr/bin, /usr/sbin 里面的文件,列出文件名并排序后,以 md5sum 分析其指纹码。 分析完毕后,将数据放至于 /root/rawdata.md5 中。
进行文件的分区 :
前往 /dev/shm/check 目录,在该目录下,以 dd 这个指令,建立一个 200M 的巨型档案,文件名为 bigfile。
将该档案以 20M 为单位,进行切割,文件名为 sfile?? 这样,那个 ?? 为自行建立的分割文件名。
透过 cat 的功能,将 sfile?? 再次组合成为巨型档案,文件名为bigfile2
透过 cmp 的功能,比较 bigfile 与 bigfile2 是否为相同的档案?
作业 (不提供学生答案,仅提供教师参考答案)
作业硬盘操作帮助:
开启云端虚拟机前,请务必确认你开启的硬盘是'unit08',否则就会做错题目
若要使用图形界面,请务必使用 student 身份登入,若需要切换身份,再启用终端机处理。
若有简答题需要使用中文,请自行以第一堂课的动作自行处理输入法安装。
每部虚拟机均有独特的网卡地址,请勿使用他人硬盘上传,否则计分为 0 分。
每位同学均有自己的 IP 尾数,请先向老师询问您的 IP 尾数,才可以进行作业上传。
最终上传作业结果,请务必使用 root 身份上传。
进入操作硬盘后,先用 root 身份执行 vbird_book_setup_ip, 执行流程请参考:vbird_book_setup_ip
作业当中,某些部份可能为简答题~若为简答题时,请将答案写入 /home/student/ans.txt 当中,并写好正确题号,方便老师订正答案。 请注意,文件名写错将无法上传!
请使用 root 的身份进行如下实做的任务。 直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。
(30%)请登录这次的操作系统环境,并且依据在线的环境实做底下的题目之后,将题目的要求(指令或者是结果) 写入到 /root/ans08.txt 文件内:
当执行完成 mysha.sh 这个命令之后,该指令的回传值为多少,请写下 (1)用什么指令显示回传值? (2)回传值是多少?
在不通过 bc 这个指令的情况下,如何以 bash 的功能,计算一年有几秒? 亦即如何计算出 60*60*24*365 的结果? (1)写下指令, (2)写出结果
使用 find / 找出全系统的文件名,然后将所有数据 (包括正确与错误) 全部写入 /root/find_filename.txt, 请写下达成此目标的完整指令串。
写下一段命令(主要以echo来达成的),执行该段指令会输出' My $HOSTNAME is 'XXX' ',其中 XXX 为使用 hostname 这个指令所输出的主机名称。 例如主机名称为 station1 时,该串指令会输出' My $HOSTNAME is 'station1''。 该串命令在任何主机均可执行,但都会输出不同的消息(因为主机名不一样所致)
管理员 (root) 执行 mv 时,由于默认 alias 的关系,都会主动的加上 mv -i 此选项。 假设有个来源文件名 orifile 以及目标目录名称 desdir , 如果想要将 orifile 移动到 desdir 去的时候,请写下两个方法,让 root 执行 mv 时,不会有 -i 的默认选项 (不能 unalias 的情况下)
透过『 ll /usr/sbin/* /usr/bin/* 』搭配 cut 与 sort, uniq 等指令来设计一个指令串,执行该指令串之后会输出如下的画面, 请写下该指令串:(底下画面为示意图,实际输出的个数可能会有些许差异)
1 r-s--x--- 1 rw-r--r-- 10 rwsr-xr-x 3 rws--x--x 3 rwx------ 4 rwxr-sr-x 241 rwxrwxrwx 8 rwxr-x--- 1633 rwxr-xr-x ...
(10%)制作一个名为 mycmdperm.sh 的脚本指令,放置于 /usr/local/bin 里面。 该脚本的重点是这样的:
执行脚本的方式为' mycmdperm.sh command ',其中 command 为你想要取得的指令的名称
在 mycmdperm.sh 里面,指定一个变量为 cmd,这个变量的内容为 ${1},其中 ${1} 就是该脚本后面携带的第一个参数
使用' ll $( which ${cmd} ) '来取得这个 cmd 的实际权限。
让 mycmdperm.sh 具有可执行权。
最终请执行一次该指令,例如使用' mycmdperm.sh passwd '应该会秀出 passwd 的相关权限。 不过该指令应该会执行失败, 因为上述的 (c) 指令怪怪的,似乎是'命令别名无法用在脚本内'的样子。 因此,请将这个脚本的内容修订成为没有问题的形式。 (就是将命令别名改成实际的指令操作)
(15%)制作一个名为 myfileperm.sh 的脚本指令,放置于 /usr/local/bin 里面。 该脚本的重点是这样的:
执行脚本的方式为' myfileperm.sh filename ',其中 filename 为你想要获得的文件名( 绝对路径或相对路径)
在 myfileperm.sh 里面,指定一个变量为 filename ,这个变量的内容为 ${1},其中 ${1} 就是该脚本后面携带的第一个参数
判断 filename 是否不存在,若不存在则回报『filename is non exist』
判断 filename 存在,且为一般档案,若是则回报『 filename is a reguler file 』
判断 filename 存在,且为一般目录,若是则回应『 filename is a directory』
(15%)制作一个 mymsg.sh 的脚本指令,放置于 /usr/local/bin 底下:
当执行 mymsg.sh 时,屏幕会输出底下的字样,然后结束指令。
[student@localhost ~]$ mymsg.shHollo!! My name is 'Internet Lover'... My server's kernel version is $kver I'm a student bye bye!!
上面的输出不能使用echo,请使用 cat 搭配 << eof 这样的指令语法来处理数据输出的信息。
(10%)文件和文件内容处理方法 :
找出 /etc/services 这个档案内含有 http 的关键字那几行,且 http 只会出现在行首! 并将该数据转存成 /root/myhttpd.txt 文件
找出 examuser 这个帐号在系统所拥有的档案,并将这些文件'移动'到 /root/examuser 目录中
(10%)root 的 bash 环境操作设定: (主要是修改 .bashrc 喔! 且若指令内的指令需要用到 $ 时,得输入 \$ 才可以)
做一个命令别名为 myip 的指令,这个指令会通过 ifconfig 的功能,显示出 ens3 这张网卡的 IP (只要 IP 就好喔! )。 例如 IP 为 192.168.251.12 时,则输入 myip 这个指令,屏幕只会输出 192.168.251.12 的意思。
建立一个命令别名 myerr 这个指令,这个指令会将『 echo "I am error message" 』这个讯息传输到 standard error output 去! 亦即当执行' (myerr) '时,会在屏幕上出现 I am error message,但是执行' (myerr) 2> /dev/null '时,屏幕不会有任何讯息的输出。
(10%)建立一个名为 /root/split 的目录,进行如下的行为:
将 /etc/services 复制到本目录下
假设 services 容量太大了,现在请以 100K 为单位,将该文件拆解成 file_aa, file_ab, file_ac.. 文件名文件, 每个文件最大为 100K (请自行 man split 去处理)
作业结果传输:请以 root 的身份执行 vbird_book_check_unit 指令上传操作结果。 正常执行完毕的结果应会出现【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字样。 若需要查阅自己上传资料的时间, 请在操作系统上面使用浏览器查询: http://192.168.251.254 检查相对应的课程档案。 相关流程请参考: vbird_book_check_unit
评论专区