日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Shell概述

發布時間:2024/9/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Shell概述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • Shell
      • Shell 腳本是什么?
      • 語法級
        • 可以在 Shell 腳本中使用哪些類型的變量?
        • Shell 腳本中 `if` 語法如何嵌套?
        • Shell 腳本中 `case` 語句的語法?
        • Shell 腳本中 `for` 循環語法?
        • Shell 腳本中 `while` 循環語法?
        • 如何使腳本可執行?
        • 在 Shell 腳本如何定義函數呢?
      • 編程題
        • 判斷一文件是不是字符設備文件,如果是將其拷貝到 `/dev` 目錄下?
        • 添加一個新組為 class1 ,然后添加屬于這個組的 30 個用戶,用戶名的形式為 stdxx ,其中 xx 從 01 到 30 ?
        • 寫一個 sed 命令,修改 `/tmp/input.txt` 文件的內容?
  • 一、工作中寫過的腳本
  • 二、如何獲取一個文件每一行的第三個元素?
  • 三、 shell 函數能解決什么實際問題?
  • 四、使用 awk 統計 httpd 訪問日志中每個客戶端 IP 的出現次數?
  • 五、正則表達式符號: *、+、?、[]、[^]、\{n\}分別代表什么含義?
  • 六、shell 中對變量字串進行截取的方式有哪些?
  • 七、編寫腳本,用戶輸入密碼,腳本判斷密碼是否正確,輸入正確則提示正確,連續輸入錯誤密碼 3 次,則報警?
  • 八、編寫腳本,自動生成一個 8 位隨機密碼?
  • 九、遞歸函數,遍歷目錄
  • 十、shell實現nginx日志自動切割
  • 十一、冒泡算法
  • 十二、特殊符號

Shell

Shell 腳本是什么?

一個 Shell 腳本是一個文本文件,包含一個或多個命令。作為系統管理員,我們經常需要使用多個命令來完成一項任務,我們可以添加這些所有命令在一個文本文件(Shell 腳本)來完成這些日常工作任務。

什么是默認登錄 Shell ?

在 Linux 操作系統,"/bin/bash" 是默認登錄 Shell,是在創建用戶時分配的。

使用 chsh 命令可以改變默認的 Shell 。示例如下所示:

## chsh <用戶名> -s <新shell> ## chsh ThinkWon -s /bin/sh

在 Shell 腳本中,如何寫入注釋?

注釋可以用來描述一個腳本可以做什么和它是如何工作的。每一行注釋以 # 開頭。例子如下:

#!/bin/bash ## This is a command echo “I am logged in as $USER

語法級

可以在 Shell 腳本中使用哪些類型的變量?

在 Shell 腳本,我們可以使用兩種類型的變量:

  • 系統定義變量

    系統變量是由系統系統自己創建的。這些變量通常由大寫字母組成,可以通過 set 命令查看。

  • 用戶定義變量

    用戶變量由系統用戶來生成和定義,變量的值可以通過命令 "echo $<變量名>" 查看。

Shell腳本中 $? 標記的用途是什么?

在寫一個 Shell 腳本時,如果你想要檢查前一命令是否執行成功,在 if 條件中使用 $? 可以來檢查前一命令的結束狀態。

  • 如果結束狀態是 0 ,說明前一個命令執行成功。例如:

    root@localhost:~## ls /usr/bin/shar /usr/bin/shar root@localhost:~## echo $? 0
  • 如果結束狀態不是0,說明命令執行失敗。例如:

    root@localhost:~## ls /usr/bin/share ls: cannot access /usr/bin/share: No such file or directory root@localhost:~## echo $? 2

Bourne Shell(bash) 中有哪些特殊的變量?

下面的表列出了 Bourne Shell 為命令行設置的特殊變量。

內建變量 解釋 $0 命令行中的腳本名字 $1 第一個命令行參數 $2 第二個命令行參數 ….. ……. $9 第九個命令行參數 $## 命令行參數的數量 $* 所有命令行參數,以空格隔開

如何取消變量或取消變量賦值?

unset 命令用于取消變量或取消變量賦值。語法如下所示:

## unset <變量名>

Shell 腳本中 if 語法如何嵌套?

if [ 條件 ] then 命令1 命令2 ….. else if [ 條件 ] then 命令1 命令2 …. else 命令1 命令2 ….. fi fi

在 Shell 腳本中如何比較兩個數字?

在 if-then 中使用測試命令( -gt 等)來比較兩個數字。例如:

#!/bin/bash x=10 y=20 if [ $x -gt $y ] then echo “x is greater than y” else echo “y is greater than x” fi

Shell 腳本中 case 語句的語法?

基礎語法如下:

case 變量 in 值1) 命令1 命令2 ….. 最后命令 !! 值2) 命令1 命令2 …… 最后命令 ;; esac

Shell 腳本中 for 循環語法?

基礎語法如下:

for 變量 in 循環列表 do 命令1 命令2 …. 最后命令 done

Shell 腳本中 while 循環語法?

如同 for 循環,while 循環只要條件成立就重復它的命令塊。
不同于 for循環,while 循環會不斷迭代,直到它的條件不為真。

基礎語法:

while [ 條件 ] do 命令… done

do-while 語句的基本格式?

do-while 語句類似于 while 語句,但檢查條件語句之前先執行命令(LCTT 譯注:意即至少執行一次。)。下面是用 do-while 語句的語法:

do { 命令 } while (條件)

Shell 腳本中 break 命令的作用?

break 命令一個簡單的用途是退出執行中的循環。我們可以在 while 和 until 循環中使用 break 命令跳出循環。

Shell 腳本中 continue 命令的作用?

continue 命令不同于 break 命令,它只跳出當前循環的迭代,而不是整個循環。continue 命令很多時候是很有用的,例如錯誤發生,但我們依然希望繼續執行大循環的時候。

如何使腳本可執行?

使用 chmod 命令來使腳本可執行。例子如下:chmod a+x myscript.sh 。

#!/bin/bash 的作用?

#!/bin/bash 是 Shell 腳本的第一行,稱為釋伴(shebang)行。

  • 這里 # 符號叫做 hash ,而 ! 叫做 bang。
  • 它的意思是命令通過 /bin/bash 來執行。

如何調試 Shell腳本?

  • 使用 -x' 數(sh -x myscript.sh)可以調試 Shell腳本。
  • 另一個種方法是使用 -nv 參數(sh -nv myscript.sh)。

如何將標準輸出和錯誤輸出同時重定向到同一位置?

  • 方法一:2>&1 (如## ls /usr/share/doc > out.txt 2>&1 ) 。
  • 方法二:&> (如## ls /usr/share/doc &> out.txt ) 。

在 Shell 腳本中,如何測試文件?

test 命令可以用來測試文件。基礎用法如下表格:

Test 用法 -d 文件名 如果文件存在并且是目錄,返回true -e 文件名 如果文件存在,返回true -f 文件名 如果文件存在并且是普通文件,返回true -r 文件名 如果文件存在并可讀,返回true -s 文件名 如果文件存在并且不為空,返回true -w 文件名 如果文件存在并可寫,返回true -x 文件名 如果文件存在并可執行,返回true

在 Shell 腳本如何定義函數呢?

函數是擁有名字的代碼塊。當我們定義代碼塊,我們就可以在我們的腳本調用函數名字,該塊就會被執行。示例如下所示:

$ diskusage () { df -h ; } 譯注:下面是我給的shell函數語法,原文沒有 [ function ] 函數名 [()] { 命令; [return int;] }

如何讓 Shell 就腳本得到來自終端的輸入?

read 命令可以讀取來自終端(使用鍵盤)的數據。read 命令得到用戶的輸入并置于你給出的變量中。例子如下:

## vi /tmp/test.sh #!/bin/bash echo ‘Please enter your name’ read name echo “My Name is $name## ./test.sh Please enter your name ThinkWon My Name is ThinkWon

如何執行算術運算?

有兩種方法來執行算術運算:

  • 1、使用 expr 命令:## expr 5 + 2 。
  • 2、用一個美元符號和方括號($[ 表達式 ]):test=$[16 + 4] ; test=$[16 + 4] 。

編程題

判斷一文件是不是字符設備文件,如果是將其拷貝到 /dev 目錄下?

#!/bin/bash read -p "Input file name: " FILENAME if [ -c "$FILENAME" ];thencp $FILENAME /dev fi

添加一個新組為 class1 ,然后添加屬于這個組的 30 個用戶,用戶名的形式為 stdxx ,其中 xx 從 01 到 30 ?

#!/bin/bash groupadd class1 for((i=1;i<31;i++)) doif [ $i -le 10 ];thenuseradd -g class1 std0$ielseuseradd -g class1 std$ifi done

編寫 Shell 程序,實現自動刪除 50 個賬號的功能,賬號名為stud1 至 stud50 ?

#!/bin/bash for((i=1;i<51;i++)) douserdel -r stud$i done

寫一個 sed 命令,修改 /tmp/input.txt 文件的內容?

要求:

  • 刪除所有空行。
  • 一行中,如果包含 “11111”,則在 “11111” 前面插入 “AAA”,在 “11111” 后面插入 “BBB” 。比如:將內容為 0000111112222 的一行改為 0000AAA11111BBB2222 。
[root@~]## cat -n /tmp/input.txt1 00001111122223 0000111112222224 11111000000222567 1111111111111222222222228 22111111119 11222222210 112211## 刪除所有空行命令 [root@~]## sed '/^$/d' /tmp/input.txt 000011111222 000011111222222 11111000000222 111111111111122222222222 2211111111 112222222 1122## 插入指定的字符 [root@~]## sed 's#\(11111\)#AAA\1BBB#g' /tmp/input.txt 0000AAA11111BBB222 0000AAA11111BBB222222 AAA11111BBB000000222 AAA11111BBBAAA11111BBB11122222222222 22AAA11111BBB111 112222222 1122

一、工作中寫過的腳本

1、監控腳本(監控系統、監控服務、監控硬件信息、監控性能、安全監控等)

2、系統初始化腳本(創建目錄,創建賬戶,安裝軟件包,設置權限,修改內核參數等)

一鍵部署(源碼安裝腳本)

3、備份腳本(自動備份數據庫,備份網站數據,備份日志,備份配置文件等)

4、日志分析腳本(分析日志數據,匯總并統計相關信息,如 PV、UV 等)

二、如何獲取一個文件每一行的第三個元素?

# awk ‘{print $3}’ 文件名

備注:awk 支持按列輸出,通過內置變量$1,$2,$3…可以單獨顯示任意列,默認列是以

空格或 Tab 縮進為分隔符,也可以使用-F 選項指定其他分隔符。

三、 shell 函數能解決什么實際問題?

定義函數的格式:

function 函數名{

代碼塊

}

函數名(){

代碼塊

}

使用函數可以避免代碼重復

使用函數可以將大的工程分割為若干小的功能模塊,代碼的可讀性更強

四、使用 awk 統計 httpd 訪問日志中每個客戶端 IP 的出現次數?

# awk ‘{ip[$1]++}END{for(i in ip){print ip[i],i}}’ /var/log/httpd/access_log

備注:定義數組,數組名稱為 ip,數字的下標為日志文件的第 1 列(也就是客戶端的 I

P 地址)

,++的目的在于對客戶端進行統計計數,客戶端 IP 出現一次計數器就加 1。END

中的指令在讀取完文件后執行,通過循環將所有統計信息輸出。

4、哪些方式可以將標準輸出和錯誤輸出重定向到文件?

答案:

# 命令 &> 文件名

# 命令 > 文件名 1 2> 文件名 2

# 命令 > 文件名 2>&1

# 命令 &>> 文件名

# 命令 >> 文件名 1 2>> 文件名 2

# 命令 >> 文件名 2>&1

五、正則表達式符號: *、+、?、[]、[^]、{n}分別代表什么含義?

*表示匹配前面的字符出現了任意次(包括 0 次)

+表示匹配前面的字符出現了至少 1 次(1 次或多次)

?表示匹配前面的字符出現了 0 次或 1 次

[]表示集合,匹配集合中的任意單個字符

[^]表示對集合取反

{n}表示精確匹配前面的字符出現了 n 次

六、shell 中對變量字串進行截取的方式有哪些?

# echo ${變量名:開始位置:長度} #注意,起始位置從 0 開始

# expr substr $變量名 #注意,起始位置從 1 開始

# echo $變量名 |

開始位置 長度

cut -b 開始位置-結束位置 #注意,起始位置從 1 開始

\7. 使用 sed 命令如何將文件中所有的大寫字母 Q 轉換為小寫字母 q?

答案:

# sed -i ‘s/Q/q/g’ 文件名

七、編寫腳本,用戶輸入密碼,腳本判斷密碼是否正確,輸入正確則提示正確,連續輸入錯誤密碼 3 次,則報警?

vim test.sh#!/bin/bashinit=123456for I in {1..3}doread -p "請輸入密碼:" passif [ $pass == $init ];thenecho "密碼正確"breakfidoneecho "警告:密碼錯誤"

八、編寫腳本,自動生成一個 8 位隨機密碼?

答案:

vim test.sh#!/bin/bashStr="abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"pass=""for i in {1..8}donum=$[RANDOM%${#Str}]tmp=${Str:num:1}pass+=$tmpdoneecho $pass

九、遞歸函數,遍歷目錄

遞歸遍歷目錄

通過定義遞歸函數 files來實現

Shell也可以實現遞歸函數,就是可以調用自己本身的函數。在Linux系統上編寫Shel腳本的時候,經常需要遞歸遍歷系統的目錄,列出目錄下的文件和目錄,逐層遞歸列出,并對這些層級關系進行展示。具體的實現過程如下所示。

function list files(){ for f in `ls $1`; do if [-d"$1/Sf"]: then echo"$2$f" list_files "$1/$2" " $2" else echo "$2$" fi done}list_files "/var/log" "

十、shell實現nginx日志自動切割

腳本思路【按天分割日志】

a、獲取昨天的日期(date -d yesterday +%Y%m%d),用來作為分割后日志的名稱

b、將源日志文件移動到新的nohuplogs文件夾里,并按時間重命名

c、在源日志文件夾(logs)里新建默認日志文件(access.log)

d、給nginx一個信號量,重新打開日志

f、設置一個定時任務,定時執行日志切割的腳本

操作步驟

a、新建日志分割的文件夾nohuplogs(mkdir /jboss/nginx/nohuplogs)

b、編寫腳本,暫且命名為:splitlogs.sh吧,腳本內容如下:

LOGPATH=/jboss/nginx/logs/access.logBASEPATH=/jboss/nginx/nohuplogsLOGBAK=$BASEPATH/$(date -d yesterday +%Y%m%d).log#echo $LOGBAKmv $LOGPATH $LOGBAKtouch $LOGPATHkill -USR1 `cat /jboss/nginx/logs/nginx.pid

`

c、配置定時任務 crontab -e,如下圖,增加日志分割的腳本,每天晚上23點59分切割

59 23 * * * sh /jboss/nginx/splitlogs.sh

十一、冒泡算法

請結合使用冒泡排序方法把 123.txt 文件中的數字按照降序排序輸出在一行當中,并要求沒有重復數字。(20分)

cat 123.txt

1 4 7 9

2 5 8 3

3 6 9 7

#!/bin/bashmyarray() {array=(`echo $@`)\#echo ${array[*]}a=${#array[*]}for ((i=1; i<$a; i++))do for ((j=0; j<$a-i; j++)) do if [ ${array[$j]} -lt ${array[$[$j + 1]]} ];then temp=${array[$j]} array[$j]=${array[$[$j+1]]} array[$[$j+1]]=$temp fi donedoneecho ${array[*]}}

###主體代碼

list=`for i in $(cat 123.txt); do echo $i; done | sort -n | uniq`a=0for value in $listdo arr[$a]=$value let a++doneresult=`myarray ${arr[*]}`

echo “排序后數組為:$result”

監控網站狀態是否正常,異常發郵件

題目要求:

寫一個shell腳本,通過curl -I 返回狀態碼來判定所訪問的網站是否正常,比如當代碼狀態200,才算正常

寫一個發郵件的腳本

習題分析:

1、關鍵問題,截取出代碼狀態

2、在寫出該shell腳本時,應該先在命令下面使用curl -I http://www.51xit.top/命令測試,然后通過awk截取到狀態碼

3、寫發郵件的腳本,用的是sendEmail。生產環境有配套的模板

4、判斷和發郵件關聯

curl -I http://www.51xit.top/

我們抓包會有交互信息 200

###創建觸發器及郵件報警測試##

【安裝郵件組件】

[root@tang ~]# wget http://caspian.dotconf.net/menu/Software/SendEmail/sendEmail-v1.56.tar.gz

[root@tang ~]# tar -zxvf sendEmail-v1.56.tar.gz

[root@tang ~]# cp sendEmail-v1.56/sendEmail /usr/local/bin/

[root@tang ~]# chmod 755 /usr/local/bin/sendEmail

[root@tang ~]# vi /opt/sendEmail.sh

#!/bin/bash

#

# Filename: SendEmail.sh

# Revision: 1.0

# Date: 2019/05/29

# Author: Qicheng

# Email:

# Website: http://51xit.top/

# Description: tang郵件告警腳本

# Notes: 使用sendEmail

#

# 腳本的日志文件

LOGFILE="/tmp/Email.log"

:>"$LOGFILE"

exec 1>"$LOGFILE"

exec 2>&1

SMTP_server=‘smtp.qq.com’ # SMTP服務器,變量值需要自行修改

username=‘1581273154@qq.com’ # 用戶名,變量值需要自行修改

password=‘cgdxhxqddtrafijh’ # 密碼(QQ郵箱用的是授權碼),變量值需要自行修改

from_email_address=‘1581273154@qq.com’ #### 發件人Email地址,變量值需要自行修改

to_email_address="$1" # 收件人Email地址,tang傳入的第一個參數

message_subject_utf8="$2" # 郵件標題,tang傳入的第二個參數

message_body_utf8="$3" # 郵件內容,tang傳入的第三個參數

# 轉換郵件標題為GB2312,解決郵件標題含有中文,收到郵件顯示亂碼的問題。

message_subject_gb2312=`iconv -t GB2312 -f UTF-8 << EOF

$message_subject_utf8

EOF`

[ KaTeX parse error: Expected 'EOF', got '&' at position 11: ? -eq 0 ] &?& message_subje…message_subject_gb2312" || message_subject="$message_subject_utf8"

# 轉換郵件內容為GB2312,解決收到郵件內容亂碼

message_body_gb2312=`iconv -t GB2312 -f UTF-8 << EOF

$message_body_utf8

EOF`

[ KaTeX parse error: Expected 'EOF', got '&' at position 11: ? -eq 0 ] &?& message_body=…message_body_gb2312" || message_body="$message_body_utf8"

# 發送郵件

sendEmail=’/usr/local/bin/sendEmail’

set -x

sendEmail?s"sendEmail -s "sendEmail?s"SMTP_server" -xu “username"?xp"username" -xp "username"?xp"password” -f “fromemailaddress"?t"from_email_address" -t "frome?maila?ddress"?t"to_email_address” -u “messagesubject"?m"message_subject" -m "messages?ubject"?m"message_body” -o message-content-type=text -o message-charset=gb2312

[root@tang ~]# chmod +x /opt/sendEmail.sh

[root@tang ~]# /opt/sendEmail.sh 1581273154@qq.com 測試 測試

監控磁盤情況,異常發郵件

#!/bin/bashdisk_sda1=df -h |sed -n '3p'|awk '{print $4}'|cut -f 1 -d '%'if ((disk_sda1 > 80));then echo “this is error” echo date “192.168.56.128 this is over 70%” |mail -s “disk over 70%” 12345300@qq.com,5645645@qq.comelse echo “this is ok”fi

計劃任務:

[root@localhost tmp]# crontab -e

添加

3個小時檢查一次\* */3 * * * /var/tmp/check_disk.sh或者十分鐘檢查一次*/10 * * * * /var/tmp/check_disk.sh

十二、特殊符號

$0:當前腳本的文件名

$n:第n個位置參數

?:傳遞給腳本或函數的所有參數,*:傳遞給腳本或函數的所有參數,?*會將這些參數視為一個整體

@:傳遞給腳本或函數的所有參數,@:傳遞給腳本或函數的所有參數,@@會將所有參數當作同一字符串中的多個獨立的單詞

$#:腳本運行時攜帶的參數個數

$*:表示所有位置參數的內容

$?:最近一個命令的退出狀態碼

$$:當前shell的進程ID(PID)

$!:最近一個后臺命令的PID

!!:執行上一條命令

IFS:內部字段分隔符,IFS環境變量定義了shell用作字段分隔符的一系列字符。默認情況下,shell會將下列字符當做字段分隔符:

  • 空格
  • 制表符
  • 換行符

&>:將STDERR和STDOUT的輸出重定向到同一個輸出文件

&-:要關閉文件描述符,可以將它重定向到特殊符號&-

.:點操作符,點操作符是source命令的別名,它會在shell上下文中執行點操作符指定的腳本,而不是創建一個新的shell。

[ 操作符 文件或目錄 ]

常用的測試操作符

-d:測試是否為目錄(Directory)

-e:測試目錄或文件是否存在(Exist)

-f:測試是否為文件(File)

-r:測試當前用戶是否有權限讀取(Read)

-w:測試當前用戶是否有權限寫入(Write)

-x:測試當前用戶是否有權限執行(eXcute)

總結

以上是生活随笔為你收集整理的Shell概述的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。