Shell編程入門基礎上

前言

為什么學 Shell

Shell 腳本語言是實現 Linux/UNIX 系統管理及自動化運維所必備的重要工具, Linux/UNIX 系統的底層及基礎應用軟件的核心大都涉及 Shell 腳本的內容。每一個合格 的Linux 系統管理員或運維工程師,都需要能夠熟練地編寫 Shell 腳本語言,并能夠閱讀系統及各類軟件附帶的 Shell 腳本內容。只有這樣才能提升運維人員的工作效率,適 應曰益復雜的工作環境,減少不必要的重復工作,從而為個人的職場發展奠定較好的基礎

什么是 shell

Shell 是一個命令解釋器,它在操作系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操作系統,并處理各種各樣的操作系統的輸出結果,輸出屏幕返回給用戶。
1052714-20190717163024708-1154669583.png

這種對話方式可以是:

  • 交互的方式:從鍵盤輸入命令,通過 /bin/bash 的解析,可以立即得到 Shell 的回應
[root@mico ~]# echo "hello"
hello
[root@mico ~]# pwd
/root
[root@mico ~]#  
  • 非交互的方式: 腳本

什么是Shell腳本

  • Linux命令、變量和流程控制語句等有機的結合起來并以程序文件形式執行,該程序稱為shell腳本。
  • Shell腳本語言是弱類型語言(無須定義變量的類型即可使用), shell腳本擅長處理純文本類型的數據,而linux中,幾乎所有的配置文件,日志,都是純文本類型文件。

腳本語言的種類

編譯型語言

    定義:指用專用的編譯器,針對特定的操作平臺(操作系統)將某種高級語言源代碼一次性翻譯成可被硬件平臺直接運行的二進制機器碼(具有操作數,指令、及相應的格式),這個過程叫做編譯(./configure  make makeinstall );編譯好的可執行性文件(.exe),可在相對應的平臺上運行(移植性差,但運行效率高)。典型的編譯型語言有, C語言、C++等。另外,Java語言是一門很特殊的語言,Java程序需要進行編譯步驟,但并不會生成特定平臺的二進制機器碼,它編譯后生成的是一種與平臺無關的字節碼文件(*.class)(移植性好的原因),這種字節碼自然不能被平臺直接執行,運行時需要由解釋器解釋成相應平臺的二進制機器碼文件;大多數人認為Java是一種編譯型語言,但我們說Java即是編譯型語言,也是解釋型語言也并沒有錯。

解釋型語言

    定義:指用專門解釋器對源程序逐行解釋成特定平臺的機器碼并立即執行的語言;相當于把編譯型語言的編譯鏈接過程混到一起同時完成的。解釋型語言執行效率較低,且不能脫離解釋器運行,但它的跨平臺型比較容易,只需提供特定解釋器即可。常見的解釋型語言有, Python(同時是腳本語言)與Ruby等。

腳本語言

    定義:為了縮短傳統的編寫-編譯-鏈接-運行(edit-compile-link-run)過程而創建的計算機編程語言。特點:程序代碼即是最終的執行文件,只是這個過程需要解釋器的參與,所以說腳本語言與解釋型語言有很大的聯系。腳本語言通常是被解釋執行的,而且程序是文本文件。

典型的腳本語言有,JavaScript,Python,shell等。

其他常用的腳本語句種類

  • PHP是網頁程序,也是腳本語言。是一款更專注于 web 頁面開發(前端展示)的腳本語言,例如:Dedecms,discuz。PHP 程序也可以處理系統日志,配置文件等,php 也可以調用系統命令。
  • Perl 腳本語言。比 shell 腳本強大很多,語法靈活、復雜,實現方式很多,不易讀,團隊協作困難,但仍不失為很好的腳本語言,存世大量的程序軟件。MHA 高可用 Perl 寫的
  • Python,不但可以做腳本程序開發,也可以實現 web 程序以及軟件的開發。近兩年越來越多的公司都會要求會 Python。

Shell腳本與 php/perl/python 語言的區別和優勢?

shell 腳本的優勢在于處理操作系統底層的業務 (linux 系統內部的應用都是 shell 腳本完成)因為有大量的 linux 系統命令為它做支撐。2000 多個命令都是 shell 腳本編程的有力支撐,特別是grep、awk、sed 等。例如:一鍵軟件安裝、優化、監控報警腳本,常規的業務應用,shell 開發更簡單快速,符合運維的簡單、易用、高效原則。PHP、Python 優勢在于開發運維工具以及 web 界面的管理工具,web 業務的開發等。處理一鍵軟件安裝、優化,報警腳本。常規業務的應用等 php/python 也是能夠做到的。但是開發效率和復雜比用 shell 就差很多了。

系統中的shell

查看系統環境

[root@mico ~]# cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core) 
[root@mico ~]# uname -r
3.10.0-862.11.6.el7.x86_64
[root@mico ~]# getenforce 
Disabled
[root@mico ~]# systemctl status firewalld.service 
● firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)Active: inactive (dead)Docs: man:firewalld(1)
[root@mico ~]#

查看系統中的命解釋器

[root@mico ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
[root@mico ~]#

常用操作系統的默認shell

  • Linux是Bourne Again shell(bash)
  • Solaris和FreeBSD缺省的是Bourne shell(sh)
  • AIX下是Korn Shell(ksh)
  • HP-UX缺省的是POSIX shell(sh)
[root@mico ~]# echo $SHELL
/bin/bash

查看系統的 Bash 版本

[root@VM_42_34_centos /]# head -1 /etc/init.d/network 
#! /bin/bash
[root@VM_42_34_centos /]# head -1 /etc/init.d/netconsole 
#!/bin/bash

bash版本

[root@mico ~]# bash -version
GNU bash, 版本 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
許可證 GPLv3+: GNU GPL 許可證版本3或者更高 <http://gnu.org/licenses/gpl.html>這是自由軟件,您可以自由地更改和重新發布。
在法律允許的范圍內沒有擔保.

bash 破殼漏洞

使用 命令 env x='() { :;}; echo be careful' bash -c "echo this is a test"
如果返回結果為一行,則為正常,

 [root@mico ~]# env x='() { :;}; echo be careful' bash -c "echo this is a test"
this is a test
#解決辦法 升級當前的bash版本yum install update bash

bash 和 sh 的區別

早期的bash和sh稍有不同,還包含了csh和ksh的特色,但大多數腳本都可以不加修改地在sh上運行

[root@VM_42_34_centos ~]# ll /bin/bash
-rwxr-xr-x 1 root root 964544 4月  11 2018 /bin/bash
[root@VM_42_34_centos ~]# ll /bin/sh
lrwxrwxrwx 1 root root 4 8月  10 2018 /bin/sh -> bash

說明:sh為bash的軟鏈接,一般情況下,腳本開頭使用“#!/bin/bash”和"#!/bin/sh"是沒有區別的,但更規范的寫法是在腳本開頭使用“#!/bin/bash”
下面的Shell腳本是系統自帶的軟件啟動腳本的開頭部分

sh與bash 的關系

[root@mico ~]# ll /bin/sh
lrwxrwxrwx 1 root root 4 8月  10 2018 /bin/sh -> bash

/bin與 /user/bin 的關系

[root@mico ~]# ll /bin -d
lrwxrwxrwx 1 root root 7 8月  10 2018 /bin -> usr/bin

腳本書寫規范

腳本統一存放目錄

[root@mico ~]# mkdir -p /server/scripts/
[root@mico ~]# cd /server/scripts/

選擇解釋器

腳本第一行指出由哪個程序(解釋器)來執行腳本中的內容
#!/bin/bash#!/bin/sh(255個字符以內)

注意格式 ↓
其中開頭的"#!"字符又稱為幻數,在執行bash腳本的時候,內核會根據"#!"后的解釋器來確定該用那個程序解釋這個腳本中的內容。

[root@mico scripts]# head -1 /etc/init.d/*
==> /etc/init.d/functions <==
# -*-Shell-script-*-==> /etc/init.d/netconsole <==
#!/bin/bash==> /etc/init.d/network <==
#! /bin/bash==> /etc/init.d/README <==
You are looking for the traditional init scripts in /etc/rc.d/init.d,

編輯腳本使用vim

使用 .vimrc 文件,將下面的信息添加到 .vimrc 文件中,能夠快速的生成開頭的注釋信息

autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"func SetTitle()if expand("%:e") == 'sh'call setline(1,"#!/bin/bash")call setline(2, "##############################################################")call setline(3, "# File Name: ".expand("%"))call setline(4, "# Version: V1.0")call setline(5, "# Author: mico")call setline(6, "# Created Time : ".strftime("%F %T"))call setline(7, "# Description:")call setline(8, "##############################################################")call setline(9, "")endif
endfunc

使用后的效果

#!/bin/bash
##############################################################
# File Name: scripts_tmp.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-09 10:12:27
# Description:
##############################################################

在Shell腳本中,跟在#后面的內容表示注釋。注釋部分不會被執行,僅給人看。注釋可以自成一行,也可以跟在命令后面,與命令同行。要養成寫注釋的習慣,方便自己與他人。
最好不用中文注釋,因為在不同字符集的系統會出現亂碼。(字符集為zh_CN.UTF-8,為中文)。

文件名規范

名字要有意義,并且結尾以 .sh 結束(并不是必須)

開發的規范和習慣小結

  • 放在統一的目錄
  • 腳本以 .sh 為擴展名
  • 開頭指定腳本解釋器。
  • 開頭加版本版權等信息,可配置 ~/.vimrc 文件自動添加。
  • 腳本不要用中文注釋,盡量用英文注釋。
  • 代碼書寫優秀習慣
    • 成對的內容一次性寫出來,防止遺漏,如[ ]' '" "
    • [ ] 兩端要有空格,先輸入[ ],退格,輸入 2 個空格,再退格寫。
    • 流程控制語句一次書寫完,再添加內容。(if 條件 ; then 內容;fi)
    • 通過縮進讓代碼易讀。
    • 腳本中的引號都是英文狀態下的引號,其他字符也是英文狀態。

shell腳本的執行

當 Shell 腳本運行時,會先查找系統環境變量 ENV,該變量指定了環境文件(加載順序通常是 /etc/profile~/.bash_profile~/.bashrc/etc/bashrc ),在加載了上述變量文件后,Shell就開始執行腳本中的內容。
1052714-20190717163121628-745454361.png

Shell 腳本是從上至下、從左至右依次執行每一行的命令及語句的。即執行完了一個命令后再執行下一個,如果在 Shell 腳本中(即腳本嵌套)
時,就會先執行子腳本的內容,完成后再返回父腳本繼續執行父腳本內后序的命令及語句。
通常情況下,在執行 Shell 腳本時,會向系統內核請求啟動一個新進程,以便在該進程或只能怪執行腳本的命令以及子Shell 腳本。

執行腳本的辦法

執行腳本的四種方法

(1)sh/bash scripts.sh
當腳本本身沒有可執行權限時使用的方法,或腳本文件開頭沒有指定解釋器時需要使用分方法。
(2)首先chown +x ,然后./scripts.sh.path/scripts.sh
在當前路徑下執行腳本(腳本需要有執行權限),通過絕對路徑或相對路徑直接執行腳本
(3)source scripts.sh. (空格) scripts.sh
這種方法通常是使用 source. 讀入或加載指定的 shell 腳本文件(不需要執行權限),然后依次執行指定 shell 腳本中的所有語句。這些語句將在當前 shell 腳本的進程中運行(其他幾種模式都會啟動新的進程執行子腳本)。source. 命令的功能是在當前 Shell 中執行 source. 加載并執行的相關腳本文件中的命令及語句,而不是產生一個子 Shell 來執行文件中的命令。
說明.source 命令的功能相同,都是讀入腳本并執行腳本中的命令。
(4)sh < script-name 或 cat scripts-name|sh 效率低
同樣適用于bash,不過這種用法不常見。

source 與 . (點) 的作用

soucre命令

[root@mico ~]# help source  |head -2
source: source 文件名 [參數]在當前 shell 中執行一個文件中的命令。
. (點)
[root@mico ~]# help . |head -2
.: . 文件名 [參數]在當前 shell 中執行一個文件中的命令。

sh于source的區別

對比:用 source 執行腳本文件,執行過程不另開進程,腳本文件中設定的變量在當前shell中可以看到;
用 sh/bash 執行腳本文件,是在當前進程另開子進程來執行腳本命令,腳本文件中設定的變量在當前shell中不能看到。

例如

[root@VM_42_34_centos trsky]# echo 'userdir=`pwd`' >> testsource.sh
[root@VM_42_34_centos trsky]# cat testsource.sh 
userdir=`pwd`
[root@VM_42_34_centos trsky]# sh testsource.sh 
[root@VM_42_34_centos trsky]# echo $userdir[root@VM_42_34_centos trsky]# source testsource.sh 
[root@VM_42_34_centos trsky]# echo $userdir
/home/trsky
[root@VM_42_34_centos trsky]# 

由案例可知,使用 source. 執行的腳本中的變量值會傳遞到當前的 Shell 下,因為使用 source. 執行腳本不會開啟新的進程,而是在統一進程下完成腳本中所有指令的執行。
1052714-20190717163230570-1216634593.png

[root@mico scripts]# sh  mico_test.sh 
Hello World!
[root@mico ~]# echo $Mico
Mico #  sh  新建一個Shell窗口(新建一個進程)執行一個文件中的命令。[root@mico scripts]# source mico_test.sh 
Hello World!
[root@mico scripts]# echo $mico
Hello World!

面試題:

問 sh test.sh 后 echo $user 返回的結果_ ?

[root@oldboy scripts]# cat test.sh 
#!/bin/bash
user=`whoami`

Shell的變量

Shell變量的特性

Shell為弱類型語言,所以在默認情況下,在Bash Shell中是不會區分變量類型的。但Shell可以通 declare 顯示定義變量的類型。

什么是變量

變量可以分為兩類:環境變量(全局變量)和普通變量(局部變量)

  • 環境變量也可稱為全局變量,可以在創建他們的Shell及其派生出來的任意子進程shell中使用,環境變量又可分為自定義環境變量和Bash內置的環境變量
  • 普通變量也可稱為局部變量,只能在創建他們的Shell函數或Shell腳本中使用。普通變量一般是由開發者用戶開發腳本程序時創建的。
  • 特殊變量

Shell中定義變量名以及為變量內容賦值要求
變量名一般由字母、數字、下劃線組成,可以由字母或下劃線開頭

把一個命令的結果作為變量的內容賦值的方法

  • 變量名=ls
  • 變量名=$(ls)

環境變量

使用 env/declare/set/export -p 命令查看系統中的環境變量,這三個命令的的輸出方式稍有不同。

[root@mico scripts]# env
XDG_SESSION_ID=1
HOSTNAME=mico
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=10.0.0.1 5537 22
SSH_TTY=/dev/pts/0
USER=root
~~~

輸出一個系統中的環境變量

[root@mico ~]# echo $LANG
zh_CN.UTF-8

自定義環境變量

設置環境變量
exportdeclare

設置環境變量的3種方法

  • export 變量名=value
  • 變量名=value; export 變量名
  • declare -x 變量名=value

自定義全局變量的實例:

[root@VM_42_34_centos ~]# cat /etc/profile|grep Mico
export Mico='mico'
[root@VM_42_34_centos ~]# source /etc/profile
[root@VM_42_34_centos ~]# echo $MIco[root@VM_42_34_centos ~]# echo $Mico
mico
[root@VM_42_34_centos ~]# env|grep Mico
Mico=mico
[root@VM_42_34_centos ~]# 

讓環境變量永久生效的常用設置文件

  • 用戶環境變量配置
# 用戶的環境變量設置,比較常見的是用戶家目錄下的.bashrc 和 .bash_profile
[root@mico ~]# ls /root/.bashrc
/root/.bashrc
[root@mico ~]# ls /root/.bash_profile 
/root/.bash_profile
[root@mico ~]# 
  • 全局環境變量的配置
    常見的全局環境變量的配置文件如下:
/etc/profile
/etc/bashrc
/etc/profile.d/

如果要在登陸后初始化或顯示加載內容,則將腳本文件放在/etc/profile.d/下即可(無需執行權限)

設置登錄提示的兩種方式

  • /etc/motd里增加提示的字符串
[root@mico ~]# vim /etc/motd
[root@mico ~]# cat /etc/motd 
Welcome to Linux.
  • /etc/profile.d/目錄下添加腳本
[root@mico profile.d]# cat /etc/profile.d/mico.sh 
#!/bin/bash
##############################################################
# File Name: /etc/profile.d/mico.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-01 10:00:06
# Description:
##############################################################
echo "Hello, you are studing Linux"

登錄后出現

Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.Welcome to Linux.
Hello, you are studing Linux
[root@mico ~]# 

顯示與取消環境變量

  • 通過 echo 或 prinf 打印環境變量
#常見的系統環境變量
$HOME:用戶登錄時進入的目錄
$UID:當前用戶的UID(用戶標識),相當于 id-u
$PWD:當前工作目錄的絕對路徑名
$SHELL:當前Shell
$USER:當前yonghu
...
打印或刪除環境變量
#打印環境
printf "$Home\n"
echo $PWD
  • 使用unset取消環境變量
#刪除環境變量
unset PWD

普通變量

本地變量在用戶當前的Shell生存期的腳本中使用。例如,本地變量OLDBOY取值為bingbing,這個值在用戶當前Shell生存期中有意義。如果在Shell中啟動另一個進程或退出,本地變量值將無效

普通變量的定義

變量名=value    //解釋變量名
變量名='value'  //不解釋變量名
變量名="value"  //解釋變量名

定義普通變量實踐

[root@mico ~]# a=1
[root@mico ~]# b='2'
[root@mico ~]# c="3"
[root@mico ~]# echo "$a"
1
[root@mico ~]# echo "$b"
2
[root@mico ~]# echo "${c}"

提示:$變量名表示輸出變量,可以用$c和${c}兩種用法
【小結】連續普通字符串內容賦值給變量,不管用什么引號或者不用引號,它的內容是什么,打印變量就輸出什么

export命令

[root@mico ~]# help export 
export: export [-fn] [名稱[=值] ...] 或 export -p
為 shell 變量設定導出屬性。

標記每個 NAME 名稱為自動導出到后續命令執行的環境。如果提供了 VALUE
則導出前將 VALUE 作為賦值。

export命令的說明

  • 當前shell窗口及子shell窗口生效
  • 在新開的shell窗口不會生效,生效需要寫入配置文件

定義變量

[root@mico scripts]# CSLN=mico
[root@mico scripts]# export CSLN1=1
# 當前窗口查看
[root@mico scripts]# echo $CSLN
mico
[root@mico scripts]# echo $CSLN1
1
# 編寫測試腳本
[root@mico scripts]# vim quanju.sh 
#!/bin/bash
echo $CSLN
echo $CSLN1
# 使用sh執行
[root@mico scripts]# sh  quanju.sh 1
# 使用source 執行
[root@mico scripts]# source quanju.sh 
mico
1

環境變量相關配置文件

  • /etc/proflie
  • /etc/bashrc
  • ~/.bashrc
  • ~/.bash_profile
  • /etc/proflie.d/ # 目錄

四文件讀取順序(CentOS6和7都一樣)

① /etc/profile
② ~/.bash_profile
③ ~/.bashrc
④ /etc/bashrc
1052714-20190717163253094-1965759577.png

系統運行Shell的三種方式

1) 通過系統用戶登陸后默認運行的shell
2) 非登錄交互式運行Shell
3) 執行腳本運行非交互式Shell

文件讀取過程示意圖

驗證四文件讀取順序的方法

sed -i '1a echo "$(date +%T-%s) /etc/profile1" >>/tmp/mico' /etc/profile
sed -i '$a echo "$(date +%T-%s) /etc/profile2" >>/tmp/mico' /etc/profile
sed -i '1a echo "$(date +%T-%s) /etc/bashrc1" >>/tmp/mico' /etc/bashrc
sed -i '$a echo "$(date +%T-%s) /etc/bashrc2" >>/tmp/mico' /etc/bashrc
sed -i '1a echo "$(date +%T-%s) ~/.bashrc1" >>/tmp/mico' ~/.bashrc
sed -i '$a echo "$(date +%T-%s) ~/.bashrc2" >>/tmp/mico' ~/.bashrc
sed -i '1a echo "$(date +%T-%s) ~/.bash_profile1" >>/tmp/mico' ~/.bash_profile
sed -i '$a echo "$(date +%T-%s) ~/.bash_profile2" >>/tmp/mico' ~/.bash_profile

環境變量的知識小結

  • 變量名通常要大寫。
  • 變量可以在自身的Shell及子Shell中使用。
  • 常用export來定義環境變量。
  • 執行env默認可以顯示所有的環境變量名稱及對應的值。
  • 輸出時用“$變量名”,取消時用“unset變量名”。
  • 書寫crond定時任務時要注意,腳本要用到的環境變量最好先在所執行的Shell腳本中重新定義。
  • 如果希望環境變量永久生效,則可以將其放在用戶環境變量文件或全局環境變量文件里。

環境變量

環境變量一般是指用export內置命令導出的變量,用戶定義shell的運行環境。保證shell命令的正確執行。Shell通過環境變量來確定登錄用戶名、命令路徑、終端類型、登錄目錄等。如果需要永久保存環境變量,可在用戶家目錄下的.bash_profile或.bashrc(非用戶登錄模式特有,例如遠程登錄SSH)文件中,或者全局配置/etc/bashrc(非用戶登錄模式特有,如遠程SSH)或/etc/profile文件中定義。在將環境變量放入上述的文件之后,每次用戶登錄時這些變量將被初始化。

查看設置的變量:set、env、declare

  • set:輸出所有的變量,包括全局變量和局部變量。set -o 顯示bash Shell的所有參數配置信息
  • env:只顯示全局變量
  • declare:輸出所有的變量、函數、整數和已經導出的變量

變量中引號的使用

  • 只有在變量的值中有空格的時候,會使用引號。
  • 單引號與雙引號的區別在于,是否能夠解析特殊符號。
[root@mico ~]# name=vicodona
[root@mico ~]# name2='mico'
[root@mico ~]# name3="you are my heart"
[root@mico ~]# echo $name
vicodona
[root@mico ~]# echo $name2
mico
[root@mico ~]# echo $name3
you are my heart
[root@mico ~]# name4='mi co'
[root@mico ~]# echo $name4
mi co
[root@mico ~]# name5="mi co"
[root@mico ~]# echo $name5
mi co
[root@mico ~]# name6="mico $PWD"
[root@mico ~]# echo $name6
mico /root
[root@mico ~]# name6='mi co $PWD'
[root@mico ~]# echo $name6
mi co $PWD
[root@mico ~]# name7="mico $PWD"
[root@mico ~]# echo $name7
mico /root

普通變量的要求

  • 內容是純數字、簡單的連續字符(內容中不帶任何空格)時,定義時可以不加任何引號,例如:
a.MicoAge=22
b.NETWORKING=yes
  • 沒有特殊情況時,字符串一律用雙引號定義賦值,特別是多個字符串中間有空格時,例如:
a.NFSD_MODULE="no load"
b.MyName="Oldboy is a handsome boy."
  • 當變量里的內容需要原樣輸出時,要用單引號(M),這樣的需求極少,例如:
a.OLDBOY_NAME='OLDBOY'

變量使用反引號賦值

[root@mico scripts]# time=`date`
[root@mico scripts]# echo $time
2017年 12月 05日 星期二 09:02:06 CST[root@mico scripts]# file=`ls`
[root@mico scripts]# echo $file
mico_test.sh panduan.sh quanju.sh yhk.sh

使用${}

打印變量的時候防止出現“金庸新著”的問題

[root@mico ~]# time=`date`
[root@mico ~]# echo $time
2019年 07月 18日 星期四 17:47:23 CST
[root@mico ~]# echo ${time}_day
2019年 07月 18日 星期四 17:47:23 CST_day
[root@mico ~]# echo $time-day
2019年 07月 18日 星期四 17:47:23 CST-day

編寫腳本測試${}

# 使用腳本測試[root@mico ~]# vim variable.sh #!/bin/bashtime=`date`echo $timedayecho ${time}day[root@mico ~]# sh variable.sh 2019年 07月 18日 星期四 17:49:51 CSTday
名稱解釋
單引號所見即所得,即輸出時會將單引號內的所有內容都原樣輸出,或者描述為單引號里面看到的是什么就會輸出什么;這稱為強引用
雙引號(默認)輸出雙引號內的所有內容;如果內容中有命令、變量、特殊字符等,會先把變量、命令、轉義字符解析出結果,然后再輸出最終內容,推薦使用,稱為弱引用
無引號賦值時,如果變量內容中有空格,則會造成賦值不完整。而在輸出內容時,會將含有空格的字符串視為一個整體來輸出;如果內容中有命令、變量等,則會先把變量、命令解析出結果,然后輸出最終內容;如果字符串中帶有空格等特殊字符,則有可能無法完整的輸出,因此需要改加雙引號
反引號一般用于引用命令,執行的時候命令會被執行,相當于`$()`,賦值和輸出都要用命令引起來

定義變量名技巧

  • 變量名只能為字母、數字或下劃線,只能以字母或下劃線開頭。
  • 變量名的定義要有一定的規范,并且要見名知意。

示例:

MicoAge=22       #<==每個單詞的首字母大寫的寫法
mico_age=22      #<==單詞之間用"_"的寫法
micoAgeSex=man   #<==駝峰語法:首個單詞的首字母小寫,其余單詞首字母大寫
MICOAGE=22       #<==單詞全大寫的寫法
  • 一般的變量定義、賦值常用雙引號;簡單連續的字符串可以不加引號;希望原樣輸出時使用單引號。
  • 希望變量的內容是命令的解析結果時,要用反引號'',或者用$()把命令括起來再賦值。

特殊變量

位置變量

常用的特殊位置參數說明

位置變量作用說明
$0獲取當前執行的shell腳本的文件名,如果執行腳本帶路徑那么就包括腳本路徑。
$n獲取當前執行的shell腳本的第n個參數值,n=1..9,當n為0時表示腳本的文件名,如果n大于9用大括號括起來{10},參數以空格隔開。
$#獲取當前執行的shell腳本后面接的參數的總個數
$*獲取當前shell的所有傳參的參數,不加引號同$@;如果給$加上雙引號,例如: “$”,則表示將所有的參數視為單個字符串,相當于“112$3”。
$@獲取當前shell的所有傳參的參數,不加引號同$*;如果給$@加上雙引號,例如: “$@”,則表示將所有參數視為不同的獨立字符串,相當于“$1” “$2” “$3” “……”,這是將參數傳遞給其他程序的最佳方式,因為他會保留所有內嵌在每個參數里的任何空白。

$*$@ 都加雙引號時,兩者有區別,都不加雙引號時,兩者無區別。

舉例說:
腳本名稱叫 test.sh 入參三個: 1 2 3
運行 test.sh 1 2 3后
$* 為 "1 2 3"(一起被引號包住)
$@ 為 "1" "2" "3"(分別被包住)

參數實踐
[root@mico ~]# vim parameter.sh
#!/bin/bashecho $0
echo "第一個參數:" $1
echo "第二個參數:" $2
echo "第11個參數:" ${11}[root@mico ~]# sh parameter.sh 
parameter.sh
第一個參數:
第二個參數:
第11個參數:
[root@mico ~]# 
[root@mico ~]# sh parameter.sh 1 2 3 4 5 6 7 8 9 10 11
parameter.sh
第一個參數: 1
第二個參數: 2
第11個參數: 11
[root@mico ~]# 
$# 參數實踐
[root@mico ~]# cat parameter.sh 
#!/bin/bash
##############################################################
# File Name: parameter.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-18 17:50:45
# Description:
##############################################################
echo $0
echo "第一個參數:" $1
echo "第二個參數:" $2
echo "第10個參數:" ${10}
echo "第11個參數:" ${11}
echo "參數個數:" $#[root@mico ~]# sh parameter.sh 1 2 3 4 5 6 7 8 9 10 11
parameter.sh
第一個參數: 1
第二個參數: 2
第10個參數: 10
第11個參數: 11
參數個數: 11
$* 參數實踐
[root@mico ~]# vim parameter.sh#!/bin/bash
##############################################################
# File Name: parameter.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-18 17:50:45
# Description:
##############################################################
echo $0
echo "第一個參數:" $1
echo "第二個參數:" $2
echo "第10個參數:" ${10}
echo "第11個參數:" ${11}
echo "參數個數:" $#
echo "參數:"$*                               
[root@mico ~]# sh parameter.sh 1 2 3 4 5 6 7 8 9 10 11
parameter.sh
第一個參數: 1
第二個參數: 2
第10個參數: 10
第11個參數: 11
參數個數: 11
參數:1 2 3 4 5 6 7 8 9 10 11
$*$@ 對比實踐
[root@mico scripts]# set -- "I am" handsome boy..
[root@mico scripts]# echo $1
I am
[root@mico scripts]# echo $2
handsome
[root@mico scripts]# echo $3
boy..
[root@mico scripts]# echo $*
I am handsome boy..
[root@mico scripts]# echo $@
I am handsome boy..[root@mico scripts]# for i in $*;do echo $i ;done
I
am
handsome
boy..
[root@mico scripts]# for i in $@;do echo $i ;done
I
am
handsome
boy..
[root@mico scripts]# for i in "$@";do echo $i ;done
I am
handsome
boy..
[root@mico scripts]# for i in "$*";do echo $i ;done
I am handsome boy..

進程狀態變量

Shell進程的特殊狀態變量說明

位置變量作用說明
$?獲取執行上一個指令的執行狀態返回值(0為成功,非零為失敗),這個變量最常用
$$獲取當前執行的Shell腳本的進程號(PID),這個變量不常用,了解即可
$!獲取上一個在后臺工作的進程的進程號(PID),這個變量不常用,了解即可
$_獲取在此之前執行的命令或腳本的最后一個參數,這個變量不常用,了解即可

進程參數實踐

[root@mico scripts]# echo $?
0
[root@mico scripts]# echo $$
1368
[root@mico scripts]# echo $![root@mico scripts]# echo $_
Echo

Bash Shell常見的內部命令:echoevalexecexportreadshift

echo參數說明

參數參數說明
-n不要追加換行
-e啟用下列反斜杠轉義的解釋
-E顯式地抑制對于反斜杠轉義的解釋

echo' 對下列反斜杠字符進行轉義: +\n:換行 +\r:回車 +\t:橫向制表符 +\b:退格 +\v:縱向制表符 +\c`:抑制更多的輸出

定義變量的方式

三種定義變量的方式

  • 直接賦值
  • 傳參 (傳遞參數)
  • 交互式設置變量,使用read命

read命令說明

在命令行中使用

[root@mico scripts]# read
132
[root@mico scripts]# echo $REPLY 
132
[root@mico scripts]# read mico 
456
[root@mico scripts]# echo $mico
456
[root@mico scripts]# echo $REPLY 
132

在腳本中使用

[root@mico scripts]# vim mico_test.sh 
#!/bin/bash
read -p '請輸入:'  micoecho $mico
執行結果
[root@mico scripts]# sh mico_test.sh 
請輸入:mico_znix
mico_znix

read 命令的幫助說明

[root@mico scripts]# read --help
-bash: read: --: 無效選項
read: 用法:read [-ers] [-a 數組] [-d 分隔符] [-i 緩沖區文字] [-n 讀取字符數] [-N 讀取字符數] [-p 提示符] [-t 超時] [-u 文件描述符] [-s不顯示終端的任何輸入] [名稱 ...]

定義方法實踐

直接賦值方法

[root@mico ~]# cat parameter.sh 
#!/bin/bash
##############################################################
# File Name: parameter.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-18 17:50:45
# Description:
##############################################################
name=MICO
age=18
sex=girl
hobby=`ls`
ethFile=/etc/sysconfig/network-scripts/ifcfg-eth0echo $hobby
ls $ethFile
[root@mico ~]# sh parameter.sh 
default.pass Django-Blog Django-Blog.tar parameter.sh practices scripts server test.sh variable.sh
/etc/sysconfig/network-scripts/ifcfg-eth0

交互式設置變量 read

[root@mico ~]# vim keyword.sh 
#!/bin/bash
##############################################################
# File Name: keyword.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-18 18:42:31
# Description:
##############################################################
read -p "請輸入您的學號:" number
read -s -p "請輸入姓名:" name
echo
echo "您的學號:"$number
echo "您的姓名:"$name
[root@mico ~]# sh keyword.sh 
請輸入您的學號:20190729
請輸入姓名:
您的學號:20190729
您的姓名:youka

寫一個交互腳本,實現能夠定義主機名及IP地址

腳本內容↓

[root@mico ~]# cat keyword.sh 
#!/bin/bash
##############################################################
# File Name: keyword.sh
# Version: V1.0
# Author: mico
# Created Time : 2019-07-18 18:42:31
# Description:
##############################################################
read -p "請輸入您的學號:" number
read -s -p "請輸入姓名:" name
echo
echo "您的學號:"$number
echo "您的姓名:"$name[root@mico ~]# vim host_start.sh
[root@mico ~]# sh host_start.sh 
請輸入主機名:mico
請輸入IP地址的主機位:180
是否重啟服務器:{yes/no}no
請稍后手動重啟系統!

變量的子串

變量子串說明

表達式說明
${parameter}返回變量$parameter的內容
${#parameter}返回變內容的長度(按字符),也適用于特殊變量
${parameter:offset}在變量${parameter}中,從位置offset之后開始提取子串到結尾
${parameter:offset:length}在變量${parameter}中,從位置offset之后開始提取長度為length的子串
${parameter#word}從變量${parameter}開頭開始刪除最短匹配的word子串
${parameter##word}從變量${parameter}開頭開始刪除最長匹配的word子串
${parameter%word}從變量${parameter}結尾開始刪除最短匹配的word子串
${parameter%%word}從變量${parameter}結尾開始刪除最長匹配的word子串
${parameter/pattem/string}使用string代替第一個匹配的pattern
${parameter//pattem/string}使用string代替所有匹配的pattern

計算變賦值的長度

  • echo $(#Mico) :這種方式最快
  • echo $Mico|wc -L
  • expr length "$Mico"
  • echo "$Mico"|awk '{print length($0)}'
[root@mico ~]# export TEMP="Here is Linux"
[root@mico ~]# echo ${#TEMP}
13
[root@mico ~]# echo $TEMP|wc -L
13
[root@mico ~]# expr length "$TEMP"
13
[root@mico ~]# echo "$TEMP"
Here is Linux
[root@mico ~]# echo "$TEMP"|awk '{print length($0)}'
13
[root@mico ~]# time echo ${#TEMP}
13real    0m0.000s
user    0m0.000s
sys 0m0.000s
[root@mico ~]# time echo $TEMP|wc -L
13real    0m0.002s
user    0m0.000s
sys 0m0.002s
[root@mico ~]# 

截取變量中的字符

[root@mico scripts]# mico=abcABC123ABCabc
[root@mico scripts]# echo ${mico#abc}
ABC123ABCabc
[root@mico scripts]# echo ${mico##abc}
ABC123ABCabc
[root@mico scripts]# echo ${mico%abc}
abcABC123ABC
[root@mico scripts]# echo ${mico%%abc}
abcABC123ABC
[root@mico scripts]# echo ${mico#a*c}
ABC123ABCabc
[root@mico scripts]# echo ${mico##a*c}[root@mico scripts]# echo ${mico%a*c}
abcABC123ABC
[root@mico scripts]# echo ${mico%%a*c}[root@mico scripts]# echo ${mico#a*C}
123ABCabc
[root@mico scripts]# echo ${mico#a*C}
123ABCabc
[root@mico scripts]# echo ${mico##a*C}
abc
[root@mico scripts]# echo ${mico%a*c}
abcABC123ABC
[root@mico scripts]# echo ${mico%A*c}
abcABC123
[root@mico scripts]# echo ${mico%%A*c}
abc

替換變量內容

[root@mico scripts]# echo $mico
abcABC123ABCabc
[root@mico scripts]# echo ${mico/abc/mico}
micoABC123ABCabc
[root@mico scripts]# echo ${mico//abc/mico}
micoABC123ABCmico

echo $(#parameter)處理最快的原因是一般情況下調用外部命令來處理的方式與使用內置操作的速度相差較大。在Shell編程中應該盡量使用內置命令。

有關獲取字符串長度的幾種統計方法的性能比較

  • 變量自帶的計算長度的方法效率最高,在要求效率的場景中盡量多用
  • 使用管道統計的方法的效率都比較差,在要求效率的場景中盡量不用
  • 對于日常簡單的腳本計算,可以根據自己所擅長的或易用的程度去選擇

有關上述匹配刪除的小結

+#表示從幵頭刪除匹配最短。

  • ##表示從開頭刪除匹配最長。
  • %表示從結尾刪除匹配最短。
  • %%表示從結尾刪除匹配最長。
  • a*c表示匹配的突符串,*表示匹配所有,a*c 匹配開頭為 a、中間為任意多個字符、結尾為c的字符串。
  • a*C表示匹配的字符串,*表示匹配所有,a*C 匹配開頭為 a、中間為任意多個字符、結尾為C的字符串。

有關替換的小結

  • 一個“/”表示替換匹配的第-個字符串。
  • 兩個“/”表示替換匹配的所有字符串。

Shell的特殊擴展變量說明

表達式說明
${parameter:-word}如果parameter的變量值為空或未賦值,則會返回word字符串并替代變量的值用途.如果變量未定義,則返回備用的值,防止變量為空值或因未定義而導致異常
${parameter:=word}如果parameter的變量值為空或未賦值,則設置這個變量值為word,并返回其值。位置變量和特殊變量不適用用途:基本同上一個${parameter>word},但該變量又額外給parameter變量賦值了
${parameter:?word}如果parameter變量值為空或未賦值,那么word字符串將被作為標準錯誤輸出,否則輸出變量的值。用途:用于捕捉由于變量未定義而導致的錯誤,并退出程序
${parameter:+word}如果parameter變量值為空或未賦值,則什么都不做,否則word字符串將替代變量的值

變量的數值計算

Shell中常見的算術運算符號

運算符意義 順序
++ - -增加及減少,可前置/可結尾由左至右
+一元正號由右至左
-一元負號由右手至左
邏輯與由右手至左
~位的取反由右手至左
* / %乘法、除法、取余數由左至右
+加法由左至右
-減法由左至右
<< >>向左位移、向右位移由左至右
< <= > >=比較運算符由左至右
== !=相等 不相等由左至右
&位的AND由左至右
^位的Exclusive OR由左至右
|位的OR由左至右
&&邏輯AND由左至右
||邏輯OR由左至右
?:條件表達式由右至左
= += -= *= /= %= &= ^=賦值運算符

Shell中常見的算術運算命令

運算操作符與運算命令意義
(())用于整數運算的常用運算符,效率高
let用于整數運算,類似于"(())"
expr可用于整數運算,但還有很多其他的額外功能
bcLinux下的一個計算器程序(適合整數以及小數運算)
$[]用于整數的運算
awkawk既可以用于整數運算,也可以用于小數運算
declare定義變量值和屬性,-i參數可以用于定義整形變量,做運算

雙小括號(())的操作方法

運算操作符與運算命令意義
((i=i+1))此種書寫方法為運算后賦值法,即將i+1的運算結構賦值給變量i。注意,不能用"echo((i=i+1))"的形式輸出表達式的值,但可以用echo$((i=i+1))輸出其值
i=$((i+1))可以在"(())"前加$符,表示將表達式運算后復制給i
((8>7&&5==5))可以進行比較操作,還可以加入邏輯與和邏輯或,用于條件判斷
echo $((2+1))需要直接輸出運算表達式的運算結果時,可以在"(())"前加$符

【提示】上面涉及的數字及變量必須為整數(整型),不能是小數(浮點數)或字符串。后面的bcawk命令可以用于進行小數(浮點數)運算,但一般用到的較少。

僅支持整數的運算

echo $((數學運算表達式))
# 形式一
[root@mico scripts]# echo $((1 + 1))
2
[root@mico scripts]# echo $((2*7-3/6+5))
19
# 形式二
[root@mico scripts]# ((mico=2*8))
[root@mico scripts]# echo $mico
16
# 形式三
[root@mico scripts]# znix=$((2*7-3/6+5))
[root@mico scripts]# echo $znix
19
延伸產物(重要)
  • i++ 自增1
  • i-- 自減1
  • ++i
  • --i

示例:

[root@mico scripts]# i=1
[root@mico scripts]# echo $((i++))
1
[root@mico scripts]# echo $((i++))
2
[root@mico scripts]# echo $((i--))
3
[root@mico scripts]# echo $((i--))
2
[root@mico scripts]# echo $((i--))
1
[root@mico scripts]# echo $((++i))
1
[root@mico scripts]# echo $((++i))
2
[root@mico scripts]# echo $((++i))
3
[root@mico scripts]# echo $((--i))
2
[root@mico scripts]# echo $((--i))
1
[root@mico scripts]# echo $((--i))
0

記憶方法:++,--
變量a在前,表達式的值為a,然后a自增或自減,變量a在符號后,表達式值自增或自減,然后a值自增或自減。

let命令

[root@mico scripts]# i=1
[root@mico scripts]# i=i+1
[root@mico scripts]# echo $i
i+1[root@mico scripts]# i=1
[root@mico scripts]# let i=i+1
[root@mico scripts]# echo $i
2

expr 命令

  • 整數計算
  • 判斷擴展名
  • 判斷輸入是否為整數,非整數返回值為2
  • 計算變量的長度
示例
[root@mico scripts]# expr 1+1
1+1
[root@mico scripts]# expr 1 + 1
2
[root@mico scripts]# expr 1 * 1
expr: 語法錯誤
[root@mico scripts]# expr 1 \* 1
1
非整數返回值為2 示例:
[root@mico scripts]# expr 1 + 1 
2
[root@mico scripts]# echo $?
0
[root@mico scripts]# expr -1 + 1 
0
[root@mico scripts]# echo $?
1
[root@mico scripts]# expr a + 1 
expr: 非整數參數
[root@mico scripts]# echo $?
2
$[]運算符
[root@mico scripts]# echo $[1+2]
3
[root@mico scripts]# echo $[1-2]
-1
[root@mico scripts]# echo $[1*2]
2
[root@mico scripts]# echo $[1/2]
0

typeset 命令進行運算

[root@mico scripts]# typeset -i A=2017 B=2018
[root@mico scripts]# A=A+B
[root@mico scripts]# echo $A
4035

可以進行小數運算的命令

bc 命令

# 安裝 bc  依賴于base源
[root@mico scripts]# yum -y install bc交互模式測試bc命令
[root@mico scripts]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. 
1+1
2
[root@mico scripts]# echo 1+1.1|bc
2.1

免交互模式測試bc命令

[root@mico scripts]# echo 'scale=6;1/3'|bc
.333333
python 命令
[root@mico scripts]#  file `which yum `
/usr/bin/yum: Python script, ASCII text executable
[root@mico scripts]# python 
>>> import os
>>> os.system('df -h')
>>> 1+1.1
2.1
>>>exit()

awk 命令

[root@mico ~]# echo "7.7 3.8"|awk '{print ($1-$2)}'
3.9
[root@mico ~]# echo "358 113"|awk '{print ($1-3)/$2}'
3.14159
[root@mico ~]# echo "3 9"|awk '{print ($1+3)*$2}'
54
[root@backup scripts]# awk BEGIN'{print 1.2+3.3}'
4.5

運算相關練習題

【練習題】實現一個加減乘除等功能的計算器

實現腳本:

[root@mico scripts]# cat calculator.sh 
#!/bin/bashread -p "請輸入第一個整數:" a
read -p "請輸入第二個整數:" becho $a + $b =$(($a+$b))
echo $a - $b =$(($a-$b))
echo $a \* $b =$(($a*$b))
echo $a / $b =$(($a/$b))腳本執行過程:
[root@mico scripts]# sh calculator.sh 
請輸入第一個整數:12
請輸入第二個整數:12
12 + 12 =24
12 - 12 =0
12 * 12 =144
12 / 12 =1
精簡方法
[root@mico scripts]# vim calculator2.sh 
#!/bin/bashecho $(($1))腳本執行過程:
[root@mico scripts]# sh calculator2.sh  1+1
2
[root@mico scripts]# sh calculator.sh  1*9
9

【練習題】打印結果1+2+3+4+5+6+7+8+9+10=55

腳本內容

[root@mico scripts]# vim count.sh
#!/bin/bashNum=`seq -s + 1 10`
echo  $Num=$(($Num))

腳本執行結果

[root@mico scripts]# sh  count.sh
1+2+3+4+5+6+7+8+9+10=55

補充說明

shell腳本中批量注釋的方法
<<'EOF'

文件內容
EOF 或使用 exit 可以注釋其之后的所有內容(類似注釋,實質為不執行后面的內容)

轉載于:https://www.cnblogs.com/vicodona/p/11200117.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448231.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448231.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448231.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

寶寶不開心 : 減肚子大戰進行中、持續更新,看看一個月后能不能把腰瘦下來 ...

公司研發中心離家很近&#xff0c;于是來這邊后就天天回家吃吃、喝喝、睡睡 ... 中午一個半小時休&#xff0c;吃完就滾上床鋪&#xff1a;睡午覺&#xff0c;就這樣 天天過得好不愜意 ... // 每周也會發零售&#xff0c;大家都吃得樂呵呵的&#xff0c;晚上加班都是組上好些個…

內存問題提醒!結構體+protobuf做協議體發送!序列化

內存的三種分配方式&#xff1a; 1&#xff0e; 從靜態存儲區分配&#xff1a;此時的內存在程序編譯的時候已經分配好&#xff0c;并且在程序的整個運行期間都存在。全局變量&#xff0c;static變量等在此存儲。 2&#xff0e; 在棧區分配&#xff1a;相關代碼執行時創建&…

窮人邁向富翁的理財十步曲

當你每日的儲蓄隨著時間的累積&#xff0c;達到一定數量后再轉存到存款薄里&#xff0c;如此日積月累&#xff0c;就可以逐漸養成自身存錢理財的習慣。不管你做什么事情&#xff0c;是否養成了良好的習慣&#xff0c;都會決定你的成敗。理財投資也是同樣道理&#xff0c;在你養…

【融云分析】選擇IM云服務,需要看哪些核心技術指標?

IM&#xff08;即時通訊&#xff09;云服務已發展數年&#xff0c;不少企業與開發者都傾向于選擇第三方IM云服務&#xff0c;短平快地為應用添加即時通訊能力&#xff0c;但如何選擇服務商卻是個難題&#xff0c;單從簡單的功能介紹來看無法判斷&#xff0c;因為IM云服務接入后…

Nginx 配置詳解

序言 Nginx是lgor Sysoev為俄羅斯訪問量第二的rambler.ru站點設計開發的。從2004年發布至今&#xff0c;憑借開源的力量&#xff0c;已經接近成熟與完善。 Nginx功能豐富&#xff0c;可作為HTTP服務器&#xff0c;也可作為反向代理服務器&#xff0c;郵件服務器。支持FastCGI…

protocol buffers使用說明

一、什么是protocol buffers Protocol buffers是一個靈活的、高效的、自動化的用于對結構化數據進行序列化的協議&#xff0c;與XML相比&#xff0c;Protocol buffers序列化后的碼流更小、速度更快、操作更簡單。你只需要將要被序列化的數據結構定義一次(譯注&#xff1a;使用…

jeeCMS首頁加載流程

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 https://blog.csdn.net/gyshun/article/details/79669293 如果JEECMS部署完畢之后&#xff0c;在瀏覽器中輸入http://localhost:8080/jeecms&#xff0c;系統直接會按照以下步驟執行&#xff1a; 首…

車子突然溜坡追尾 駕校教練說掛P擋拉手剎不會溜坡

昨天4:44&#xff0c;朱先生來電&#xff1a;剛才登云路一個燒烤店門口&#xff0c;一輛車停在自己的車位上的&#xff0c;不知什么原因&#xff0c;突然溜坡撞上前面的一輛出租車。稀奇的是&#xff0c;這個溜坡的駕駛員全程都是車上睡覺睡著的&#xff0c;什么都不知道。記者…

VSCode 漢化、設置為 中文語言顯示 、中文界面

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Vscode是一款開源的跨平臺編輯器。默認情況下&#xff0c;vscode使用的語言為英文(us)&#xff0c;如何將其顯示語言修改成中文了&#…

c++執行vbs腳本

#include<fstream> using namespace std;int main() {fstream out("StartIE.vbs",ios::out);out<<"AppName\"啟動IE\"\n\Set WshellWScript.CreateObject(\"WScript.Shell\")\n\Set ieWScript.CreateObject(\"InternetEx…

Python-21-socket編程

一、基礎知識 1. C/S架構 C/S架構即客戶機/服務器模式。 它可以分為客戶機和服務器兩層&#xff1a; 第一層: 在客戶機系統上結合了界面顯示與業務邏輯&#xff1b; 第二層: 通過網絡結合了數據庫服務器。 簡單的說就是第一層是用戶表示層&#xff0c;第二層是數據庫層。 這里…

解決:VScode 漢化后 、設置中文后 還顯示英文的問題

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 按f1 搜索 Configore Display Language 設置 zh-cn 關閉軟件重啟。 如果重啟菜單等還是英文的&#xff0c;在商店查看已安裝的插件&…

自動擋怎么開-自動擋汽車怎么開?

汽車改用自動變速器后&#xff0c;駕駛員的操作更加簡便、駕駛更加平順&#xff0c;因此裝備自動變速器的新型轎車尤其受到了人們的青睞。不過&#xff0c;很多駕駛者初開自動擋車時&#xff0c;由于對自動變速器的結構和原理不是很了解&#xff0c;行車時經常是一個D擋走完全程…

CreateThread函數

創建一個在調用進程的虛擬地址空間內執行的線程。 要創建在另一個進程的虛擬地址空間中運行的線程&#xff0c;請使用 CreateRemoteThread函數。 語法 HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START…

nginx 的請求處理、請求的處理流程

nginx的請求處理 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 nginx使用一個多進程模型來對外提供服務&#xff0c;其中一個master進程&#xff0c;多個worker進程。master進程負責…

如何控制油門更準確?

學員問&#xff1a;平時練車還不錯&#xff0c;可是一換車就容易加大油門&#xff0c;有什么方法能很好的控制油呢&#xff1f;&#xff1f; 如何控制油門更準確&#xff1f;和調的座位有關系嗎&#xff1f;&#xff1f; 答&#xff1a;油門跟剎車被視為汽車控制的靈魂。汽車發…

使用線程——創建線程

CreateThread函數創建一個進程的新的線程。創建線程必須指定新線程要執行的代碼的起始地址。通常&#xff0c;起始地址是程序代碼中定義的函數的名稱&#xff08;有關更多信息&#xff0c;請參閱ThreadProc&#xff09;。此函數采用單個參數并返回DWORD值。一個進程可以讓多個線…

location

location (地址)&#xff1a; 是瀏覽器 window 上的一個對象&#xff0c;不僅能處理當前頁面的網絡地址&#xff0c;還可以實現頁面間的跳轉 頁面的跳轉&#xff1a; 為什么使用它&#xff1f; 使我們也可以通過腳本語言&#xff0c;也能實現 a 鏈接&#xff0c;同樣的效果&…

linux :Docker 方式 安裝 zookeeper、阿里服務器上 Docker 運行 zookeeper

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 查找官方鏡像&#xff0c;并下載鏡像&#xff1a; # 搜索鏡像&#xff1a; docker search zookeeper# 拉取鏡像&#xff1a;docker …

使用線程池功能

此示例創建自定義線程池&#xff0c;創建工作項和線程池計時器&#xff0c;并將它們與清理組關聯。該池由一個持久性線程組成。它演示了以下線程池函數的使用&#xff1a; CloseThreadpool CloseThreadpoolCleanupGroupCloseThreadpoolCleanupGroupMembersCloseThreadpoolWait…