單純提供一個相對的解答,並不是標準答案!
單純就是個解答的參考,寫完之後再來這邊查查看答案跟你想的一樣不一樣!?
# A. 先用 which 功能 [root@station10-101 ~]# which ifconfig chfn /usr/sbin/ifconfig /usr/bin/chfn # B. 再用 $() 的子程式功能 [root@station10-101 ~]# ll $(which ifconfig chfn) -rws--x--x. 1 root root 48896 11月 9 07:28 /usr/bin/chfn -rwxr-xr-x. 1 root root 97920 5月 11 2019 /usr/sbin/ifconfig透過這個子程式的功能,我們就不用手動輸入剛剛 which 搜尋到的檔名資料了!
[root@station10-101 ~]# /etc/passwd -bash: /etc/passwd: 拒絕不符權限的操作 [root@station10-101 ~]# echo $? 126 # 意思是說,沒有權限執行時,回傳值應該會是 126 的意思!
[root@station10-101 ~]# vbirdcommand bash: vbirdcommand: 找不到指令... [root@station10-101 ~]# echo $? 127 # 所以,這種情況會回傳 127 的數值
[root@station10-101 ~]# man bash ...... EXIT STATUS The exit status of an executed command is the value returned by the waitpid system call or equivalent function. Exit statuses fall between 0 and 255, though, as explained below, the shell may use values above 125 specially. Exit statuses from shell builtins and compound commands are also limited to this range. Under certain circumstances, the shell will use special values to indicate specific failure modes. For the shell's purposes, a command which exits with a zero exit status has succeeded. An exit status of zero indicates success. A non-zero exit sta‐ tus indicates failure. When a command terminates on a fatal signal N, bash uses the value of 128+N as the exit status. If a command is not found, the child process created to execute it returns a status of 127. If a command is found but is not executable, the return sta‐ tus is 126. If a command fails because of an error during expansion or redirection, the exit status is greater than zero. Shell builtin commands return a status of 0 (true) if successful, and non- zero (false) if an error occurs while they execute. All builtins return an exit status of 2 to indicate incorrect usage, generally invalid options or missing arguments. Bash itself returns the exit status of the last command executed, unless a syntax error occurs, in which case it exits with a non-zero value. See also the exit builtin command below. ......很簡單就得到沒權限是 126,而找不到檔案就是 127 囉!
[root@station10-101 ~]# ls /vbird ls: 無法存取 '/vbird': 沒有此一檔案或目錄 [root@station10-101 ~]# echo $? 2 # 很明顯,應該是要查看 ls 吧! [root@station10-101 ~]# man ls ...... Exit status: 0 if OK, 1 if minor problems (e.g., cannot access subdirectory), 2 if serious trouble (e.g., cannot access command-line argument). ...... # 結果的 2 說的是無法取得指令列所帶的參數 (args) 啊!
# 單純在指令的最後面加上資料流重導向: [student@station10-101 15:26 1 ~]$ date; uptime; uname -r > myfile.txt 日 4月 19 15:26:35 CST 2020 15:26:35 up 52 min, 2 users, load average: 0.00, 0.00, 0.00 [student@station10-101 15:26 2 ~]$ cat myfile.txt 4.18.0-147.el8.x86_64 # 很明顯的發現,上述指令分為三大部份 # 1. date # 2. uptime # 3. uname -r > myfile.txt # 所以 myfile.txt 只會保留 uname -r 的結果! # 將連續輸入的資料用大括號保留下來: [student@station10-101 15:26 3 ~]$ (date; uptime; uname -r ) > myfile.txt [student@station10-101 15:28 4 ~]$ cat myfile.txt 日 4月 19 15:28:09 CST 2020 15:28:09 up 54 min, 2 users, load average: 0.00, 0.00, 0.00 4.18.0-147.el8.x86_64大括號將連續資料包起來後,所有的輸出資料最終會彙整在一起後,再傳給 > 進行後續的動作!
# 先測試存在檔案時的狀態: [student@station10-101 16:35 16 ~]$ ls -d /etc &> /dev/null || echo no-exist && echo exist exist # 再測試不存在檔案時的狀態: [student@station10-101 16:35 16 ~]$ ls -d /vbird &> /dev/null || echo no-exist && echo exist no-exist exist我們可以很輕易的發現,若檔案存在時,指令沒啥問題,但是當檔案不存在時,卻兩者會同時出現!在這裡你要先注意:
ls -d /vbird &> /dev/null || echo no-exist && echo exist $?=2 $?=0 $?=0 執行失敗 因為失敗所以執行 因為成功所以執行所以,基本上, && 一定要放在 || 之前,否則邏輯上會出現問題喔!
# A. 使用連續指令下達的方式來處理這個任務即可: [student@station10-101 20:27 1 ~]$ test -e /etc; echo $? 0 # 答案為正確,因此是存在這個檔名的 # B. 判斷 SUID 使用 -S 來測試 [student@station10-101 20:28 3 ~]$ test -u /usr/bin/passwd ; echo $? 0 # 答案為正確,因此該檔案具有 SUID 的旗標 # C. 判斷主機名稱是否為我自己設定的樣子? [student@station10-101 20:28 4 ~]$ test "mylocalhost" == ${HOSTNAME} ; echo $? 1 # 答案為不正確,所以不是 mylocalhost 的樣式!讓我們來檢查一下: [student@station10-101 20:30 5 ~]$ echo ${HOSTNAME} station10-101.gocloud.vm # 果然不是! # D. 重新修改小指令: [root@station10-101 ~]# vim /usr/local/bin/checkfile #!/bin/bash #ls -d ${1} &> /dev/null && echo "${1} exist" || echo "${1} non-exist" test -e ${1} && echo "${1} exist" || echo "${1} non-exist" [root@station10-101 ~]# checkfile /etc /etc exist最後一題可以修改一下原本使用 ls 判斷檔案是否存在的方式,使用 test 會更直覺!!
[student@station10-101 21:24 1 ~]$ [ -e /etc ]; echo $? 0 [student@station10-101 21:24 2 ~]$ [ -u /usr/bin/passwd ]; echo $? 0 [student@station10-101 21:25 3 ~]$ [ "${HOSTNAME}" == "mylocalhost" ] ; echo $? 1
[root@station10-101 ~]# cd /dev/shm [root@station10-101 shm]# cp -a /etc . [root@station10-101 shm]# ll 總計 0 drwxr-xr-x. 135 root root 5280 4月 19 14:34 etc簡單的複製成功了!
[root@station10-101 shm]# cp -a /etc . cp:是否覆寫 './etc/xdg/user-dirs.conf'? y cp:是否覆寫 './etc/xdg/user-dirs.defaults'? y cp:是否覆寫 './etc/xdg/autostart/xdg-user-dirs.desktop'? ^C
[root@station10-101 shm]# /bin/cp -a /etc . <==這個是絕對路徑 [root@station10-101 shm]# \cp -a /etc . <==這個是略過命令別名
[student@station10-101 21:46 1 ~]$ vim .bashrc
alias cp="cp -i"
alias rm="rm -i"
alias mv="mv -i"
# A. 建立命令別名 [student@station10-101 21:48 3 ~]$ alias geterr=' echo "I am error" 1>&2 ' # 這個別名的意義是,執行 echo 後,將資料丟到錯誤訊息上面去! # B. 直接執行看看 [student@station10-101 21:49 4 ~]$ geterr I am error # 確實有訊息輸出啊! # C. 將錯誤資料丟棄 [student@station10-101 21:49 6 ~]$ geterr 2> /dev/null I am error # 咦!怎麼還是出現訊息?應該錯誤訊息會被丟棄才對! # D. 將訊息整個包起來看看: [student@station10-101 21:50 7 ~]$ (geterr) 2> /dev/null # 這次確實沒資料了!alias 命令別名畢竟是轉傳資料過一次,因此大概是執行完畢之後,才丟到外部指令來。所以,訊息已經輸出了, 最後那個 2> /dev/null 就會沒有訊息丟棄~使用小括號將訊息全部整合,那就可以將錯誤訊息最後切給 2> 了!
# A. 找尋檔名 [student@station10-101 22:04 9 ~]$ man find -name pattern Base of file name (the path with the leading directories removed) matches shell pattern pattern. Because the leading directories are removed, the file names considered for a match with -name will never include a slash, so `-name a/b' will never match anything (you probably need to use -path instead). A warning is issued if you try to do this, unless the environment variable POSIXLY_CORRECT is set. The metacharacters (`*', `?', and `[]') match a `.' at the start of the base name (this is a change in findutils-4.2.2; see sec‐ tion STANDARDS CONFORMANCE below). To ignore a directory and the files under it, use -prune; see an example in the description of -path. Braces are not recognised as being special, despite the fact that some shells including Bash imbue braces with a special meaning in shell patterns. The filename matching is performed with the use of the fnmatch(3) library function. Don't forget to enclose the pattern in quotes in order to protect it from expansion by the shell. [student@station10-101 21:53 8 ~]$ find /etc -name '*passwd*' find: ‘/etc/pki/rsyslog’: 拒絕不符權限的操作 find: ‘/etc/grub.d’: 拒絕不符權限的操作 find: ‘/etc/lvm/archive’: 拒絕不符權限的操作 find: ‘/etc/lvm/backup’: 拒絕不符權限的操作 find: ‘/etc/lvm/cache’: 拒絕不符權限的操作 find: ‘/etc/dhcp’: 拒絕不符權限的操作 /etc/security/opasswd /etc/pam.d/passwd /etc/passwd- /etc/passwd find: ‘/etc/nftables’: 拒絕不符權限的操作 find: ‘/etc/cups/ssl’: 拒絕不符權限的操作 find: ‘/etc/sssd’: 拒絕不符權限的操作 find: ‘/etc/polkit-1/rules.d’: 拒絕不符權限的操作 find: ‘/etc/polkit-1/localauthority’: 拒絕不符權限的操作 find: ‘/etc/audit’: 拒絕不符權限的操作 find: ‘/etc/libvirt’: 拒絕不符權限的操作 find: ‘/etc/firewalld’: 拒絕不符權限的操作 find: ‘/etc/sudoers.d’: 拒絕不符權限的操作 # B. 因為錯誤訊息不重要,所以,將它丟棄吧! [student@station10-101 22:07 11 ~]$ find /etc -name '*passwd*' 2> /dev/null /etc/security/opasswd /etc/pam.d/passwd /etc/passwd- /etc/passwd # C. 轉存正確訊息 [student@station10-101 22:07 12 ~]$ find /etc -name '*passwd*' 2> /dev/null > ~student/find_passwd.txt [student@station10-101 22:08 13 ~]$ cat ~student/find_passwd.txt /etc/security/opasswd /etc/pam.d/passwd /etc/passwd- /etc/passwd # D. 開始進行訊息的累加! [student@station10-101 22:10 15 ~]$ find /etc -name "*shadow*" 2> /dev/null /etc/gshadow /etc/gshadow- /etc/pam.d/sssd-shadowutils /etc/shadow- /etc/shadow [student@station10-101 22:10 16 ~]$ find /etc -name "*shadow*" 2> /dev/null >> ~student/find_passwd.txt # E. 最終看看檔案內容 [student@station10-101 22:10 17 ~]$ cat ~student/find_passwd.txt /etc/security/opasswd /etc/pam.d/passwd /etc/passwd- /etc/passwd /etc/gshadow /etc/gshadow- /etc/pam.d/sssd-shadowutils /etc/shadow- /etc/shadow
# A.B. 測試 cat 的用法 [student@station10-101 22:11 18 ~]$ cat I am VBird I am VBird HaHaHa HaHaHa [ctrl]+d # C. 測試輸入資料轉存成為檔案,無須使用 vim 喔! [student@station10-101 22:30 19 ~]$ cat > mycat.txt I am vbird HaHaHa [student@station10-101 22:32 20 ~]$ cat mycat.txt I am vbird HaHaHa # D. 讀入檔案 [student@station10-101 22:32 21 ~]$ cat < /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 # E. 讀入後轉存 [student@station10-101 22:33 22 ~]$ cat < /etc/hosts >> mycat.txt [student@station10-101 22:34 23 ~]$ cat mycat.txt I am vbird HaHaHa 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# A.B. 先用簡單的方法來處理檔名的搜尋 [student@station10-101 22:39 27 ~]$ find /etc -name '*.conf' 2> /dev/null /etc/dnf/dnf.conf /etc/dnf/plugins/copr.conf /etc/dnf/plugins/debuginfo-install.conf /etc/dnf/plugins/spacewalk.conf [student@station10-101 22:41 31 ~]$ find /etc 2> /dev/null | grep '\.conf$' # 關鍵字的部份會多出顏色的顯示!比較好! # C. 計算檔案數量 [student@station10-101 22:41 31 ~]$ find /etc 2> /dev/null | grep '\.conf$' | wc 384 384 12262 [student@station10-101 22:43 32 ~]$ find /etc 2> /dev/null | grep '\.conf$' | wc -l 384
# A. 使用 cut 來切割具有固定分隔字元的資料即可 [student@station10-101 22:44 34 ~]$ cut -d ':' -f 1,7 /etc/passwd root:/bin/bash bin:/sbin/nologin daemon:/sbin/nologin adm:/sbin/nologin lp:/sbin/nologin sync:/bin/sync ...... # B. 因為 shell 名稱很多,因此需要進行排序,排序完畢再以 uniq 去計算次數即可 [student@station10-101 22:47 35 ~]$ cut -d ':' -f 7 /etc/passwd [student@station10-101 22:48 36 ~]$ cut -d ':' -f 7 /etc/passwd | sort [student@station10-101 22:48 37 ~]$ cut -d ':' -f 7 /etc/passwd | sort | uniq -c 8 /bin/bash 1 /bin/sync 1 /sbin/halt 40 /sbin/nologin 1 /sbin/shutdown # C. 用 last 分析登入者,然後分析登入次數 [student@station10-101 22:48 40 ~]$ last [student@station10-101 22:50 41 ~]$ last | awk '{print $1}' [student@station10-101 22:50 42 ~]$ last | awk '{print $1}' | sort [student@station10-101 22:51 43 ~]$ last | awk '{print $1}' | sort | uniq -c 1 1 myuser2 20 reboot 28 root 35 student 1 wtmp # D. 只想取出 IPv4 的 IP 資料 [student@station10-101 22:51 44 ~]$ ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:85:b1:54 brd ff:ff:ff:ff:ff:ff inet 172.16.10.101/16 brd 172.16.255.255 scope global dynamic noprefixroute ens3 valid_lft 229299sec preferred_lft 229299sec inet6 fe80::5718:f7d5:ab79:9643/64 scope link dadfailed tentative noprefixroute valid_lft forever preferred_lft forever inet6 fe80::3a00:5779:893c:c714/64 scope link dadfailed tentative noprefixroute valid_lft forever preferred_lft forever inet6 fe80::f994:1f8e:f17d:903e/64 scope link dadfailed tentative noprefixroute valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:b0:2f:5d brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:b0:2f:5d brd ff:ff:ff:ff:ff:ff [student@station10-101 22:52 45 ~]$ ip addr show | grep 'inet ' inet 127.0.0.1/8 scope host lo inet 172.16.10.101/16 brd 172.16.255.255 scope global dynamic noprefixroute ens3 inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 # E. 只想要 IP 位址,因為在第二欄位,所以使用 awk 剛剛好! [student@station10-101 22:54 46 ~]$ ip addr show | grep 'inet ' | awk '{print $2}' 127.0.0.1/8 172.16.10.101/16 192.168.122.1/24 # F. 要將資料從螢幕輸出,同時輸出到檔案,就得要使用 tee 了! [student@station10-101 22:55 47 ~]$ ip addr show | grep 'inet ' | awk '{print $2}' | tee /dev/shm/myip.txt 127.0.0.1/8 172.16.10.101/16 192.168.122.1/24 [student@station10-101 22:56 48 ~]$ cat /dev/shm/myip.txt 127.0.0.1/8 172.16.10.101/16 192.168.122.1/24
# a. 計算日數 [root@station10-101 shm]# echo $(( 100*365 )) 36500 [root@station10-101 shm]# echo $(( 25*366 + 75*365 )) 36525 # b. 推算回傳值 [root@station10-101 shm]# bash -c "ls /check &> /dev/null && exit 10 || exit 20" [root@station10-101 shm]# echo $? 20 # c. 命令別名 [root@station10-101 shm]# alias mykver='echo "My hostname is \"${HOSTNAME}\" and kernel version is $(uname -r)"' [root@station10-101 shm]# mykver My hostname is "station10-101.gocloud.vm" and kernel version is 4.18.0-147.el8.x86_64
[root@station10-101 ~]# find /usr/sbin /usr/bin -type f [root@station10-101 ~]# find /usr/sbin /usr/bin -type f | sort [root@station10-101 ~]# md5sum $( find /usr/sbin /usr/bin -type f | sort ) 7fa442250efc4e6b6effc369a48d9e64 /usr/bin/[ f6b867209016bc4f3a85e51598359e91 /usr/bin/ac 1d512db4ff8a89fea2d83cbf975df759 /usr/bin/aconnect bdf4dd4aa6d4ccf2966d938d900963fa /usr/bin/addr2line b4e4a53d7bb09e8edb6caad9e081c44f /usr/bin/alias ......
# a. 建立巨型檔案 [root@station10-101 ~]# mkdir /dev/shm/check [root@station10-101 ~]# cd /dev/shm/check/ [root@station10-101 check]# dd if=/dev/zero of=bigfile bs=200M count=1 1+0 records in 1+0 records out 209715200 bytes (210 MB, 200 MiB) copied, 0.196554 s, 1.1 GB/s [root@station10-101 check]# ll 總計 204800 -rw-r--r--. 1 root root 209715200 4月 19 23:31 bigfile # b. 進行分割喔! [root@station10-101 check]# man split SYNOPSIS split [OPTION]... [FILE [PREFIX]] ...... -b, --bytes=SIZE put SIZE bytes per output file [root@station10-101 check]# split -b $(( 20*1024*1024 )) bigfile sfile [root@station10-101 check]# ll 總計 409600 -rw-r--r--. 1 root root 209715200 4月 19 23:31 bigfile -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileaa -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileab -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileac -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfilead -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileae -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileaf -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileag -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileah -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileai -rw-r--r--. 1 root root 20971520 4月 19 23:34 sfileaj # c. 將檔案組合起來吧! [root@station10-101 check]# cat sfile* > bigfile2 [root@station10-101 check]# ll bigfile* -rw-r--r--. 1 root root 209715200 4月 19 23:31 bigfile -rw-r--r--. 1 root root 209715200 4月 19 23:35 bigfile2 # d. 確認兩個檔案的內容是一模一樣的! [root@station10-101 check]# cmp bigfile bigfile2 [root@station10-101 check]# diff bigfile bigfile2 # 沒出現任何訊息,就代表兩個檔案內容完全一致! [root@station10-101 check]# md5sum bigfile* 3566de3a97906edb98d004d6b947ae9b bigfile 3566de3a97906edb98d004d6b947ae9b bigfile2 # 指紋碼相同,也代表這兩個檔案內容一致啊!