五 shell 變量與字符串操作


特點:1 shell變量沒有數據類型的區分

   2 Shell 把任何存儲在變量中的值,皆視為以字符組成的“字符串”。

     3  設定的變量值只在當前shell環境中有作用

     4   不能以數字開頭

     5   =號兩邊不能存在空格

     6  若變量值中存在空格,必須用括號將變量值括起來   I = “Jack  Black”

在編寫shell時,如果變量未賦值,后續使用時不會出現任何錯誤。如果要顯示錯誤提示,則需要命令  shopt -s -o nounset 

shopt -s -o nounset解析如下

 

 

.范例如下

[root@localhost ~]# vim test1.sh
#!/bin/bash
echo $Infomix
[root@localhost ~]# sh test1.sh
                                                # 未提示任何錯誤
[root@localhost ~]# vim test1.sh            
[root@localhost ~]# vim test1.sh
#!/bin/bash
shopt -s -o nounset   #添加錯誤提示

echo $Infomix
[root@localhost ~]# sh test1.sh
test1.sh:行4: Infomix: 為綁定變量  #提示錯誤

 

二  取得變量值

$變量名稱=${變量名稱}

如果變量作為字符的一部分輸出時,則必須用${}將變量括起來,否則shell將無法識別變量。$會將后面的所有字符當做變量的一部分,肯定是找不到變量的

[root@localhost ~]# myname='lsq'
[root@localhost ~]# echo $myname
lsq
[root@localhost ~]# echo ${myname}
lsq
[root@localhost ~]# echo hello${myname}boy
hellolsqboy
[root@localhost ~]# echo hello$mynameboy
hello

如果后面接的不是字符,也不是_下划線,則不需要{}來括起來。變量后接中文也是可以的。呵呵。

[root@localhost ~]# dir2=sbin
[root@localhost ~]# echo /usr/local/$dir2/config
/usr/local/sbin/config

$是去變量值的特殊字符,如果要顯示$怎么操作,轉義字符 \  或者用單引號括起來   '$i'

Bash除了echo之外,還提供了一個c類似的printf的語法。感覺這個東西有字符串格式化的意思。體會一下

%s  以字符串的形式顯示變量值

[root@localhost ~]# printf "%s" "$dir2"
sbin[root@localhost ~]# printf "%s\n" "$dir2" 
sbin                              #\n和c語言一樣,都是換行的意思。
[root@localhost ~]# 
[root@localhost ~]# SP='ABC 123 XYZ'
[root@localhost ~]# printf "%q\n" "$SP"
ABC\ 123\ XYZ   #%q會將變量值中的特殊字符,用\字符轉義,實例中就是在空格前加\

 

三  取消與清空變量

unset 變量名

unset -v  變量名       -v 表示取消的是變量

unset -f 函數名  -f 表示取消的是函數

清空變量值    

變量名=        跟unset的區別是,清空變量值,該變量還存在,只不過值變成空而已。unset則會將變量銷毀

四    變量和引號

雙引號和單引號的區別

前邊說過,變量賦值可以用單引號或者雙引號,但是二者是有區別的

雙引號相對於單引號可以有如下操作

1 替換變量             例

[root@localhost shellscript]# vim test2.sh
#! /bin/bash

shopt -s -o nounset
myname="Bash shell"
#echo $myname
hello="hello ,i am $myname"
echo $hello
[root@localhost shellscript]# sh test2.sh 
hello ,i am Bash shell    #將變量名myname用Bash shell 進行了替換
#但是如果我們用單引號

[root@localhost shellscript]# vim test2.sh
#! /bin/bash

 
         

shopt -s -o nounset
myname="Bash shell"
#echo $myname
#hello="hello ,i am $myname"
hello='hello ,i am ,$myname'
echo $hello

 
         

[root@localhost shellscript]# sh test2.sh
hello ,i am ,$myname   #看到了么?他不會替換,他會將變量名整體輸出

 如果要在雙引號中輸出變量名而非替換,則需要用到\轉義字符轉義

2 替換命令執行結果

3 替換算數運算結果

 四   變量的有效范圍

變量的有效范圍就是當前所處的shell環境

如果要讓變量在所有的shell都執行,那就需要將該變量設置成環境變量

通過  export 命令就可以將變量設置成環境變量。 

export testVar="hello world"
或
testVar="hello world"
export testVar

取消環境變量

testVar=
或者
unset testVar

 

五  Bash 的內置變量

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 六  設置只讀變量

readonly 命令和declare -r 命令

readonly 或  readonly -p     列出只讀屬性的變量列表

readonly -f  函數名       設置該函數不可修改

readonly -a 數組變量        設置后該數組為只讀數組

s[0]=10
s[1]=20
s[2]=30

readonly -a s     #設置該數組為只讀數組

s[3]=50            該行 會報錯

調整變量的其他屬性

 

 

[root@localhost ~]# declare -i I=60  #設定該變量為整數變量
[root@localhost ~]# echo $I
60
[root@localhost ~]# I="test"     #如果傳入字符串,則會將該變量變為0
[root@localhost ~]# echo $I
0
[root@localhost ~]# 

 

七   取別名

alias   變量名

[root@localhost ~]# alias -p   #列出別名列表
alias 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 perlll='eval `perl -Mlocal::lib`'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

 

alias  別名=指令            注意:=號兩邊不允許有空格。    如需要有空格,必須用括號括起來。如上例中alias l.='ls -d .*'    

 

unalias  取消別名

八   自定義工作環境

以一般賬號的角色工作時,默認的工作環境配置文件為

 

 這里的~目錄,一般指的是家目錄

自定義工作環境的意義:讓用戶登錄主機時,能擁有安全及易於執行命令的環境。包括  建立文件的權限  命令搜尋路徑  環境變量 命令提示符 別名  喜好比較器   顯示文件使用的顏色等

[root@localhost ~]# cd /root
[root@localhost ~]# cat .bash_profile   #這個是root的默認配置文件
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
[root@localhost /]# cd home   #這個是普通用戶的配置文件,普通用戶在家目錄 /home目錄中
[root@localhost home]# ls
ftptest  lsq
[root@localhost home]# cd lsq
[root@localhost lsq]# cat .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

管理員維護的環境配置文件一般有三個   /etc/profile     /etc/bashrc  /etc/skel目錄下的文件

其中  /etc/profile和/etc/bashrc中的設定,會影響所有賬號的使用環境。

在/etc/profile中,通常會設定 umask,PATH,多國語言環境,提示符號,別名等

這是我本機的profile

[root@localhost etc]# cat profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}


if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then 
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge

一下是本機普通用戶的配置環境,在/etc/skel目錄中

[root@localhost ~]# cd /etc/skel
[root@localhost skel]# ls
[root@localhost skel]# ls -la
總用量 28
drwxr-xr-x.   3 root root    78 4月  11 2018 .
drwxr-xr-x. 162 root root 12288 10月 14 15:36 ..
-rw-r--r--.   1 root root    18 10月 31 2018 .bash_logout
-rw-r--r--.   1 root root   193 10月 31 2018 .bash_profile
-rw-r--r--.   1 root root   231 10月 31 2018 .bashrc
drwxr-xr-x.   4 root root    39 8月  19 11:00 .mozilla
[root@localhost skel]# cat .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH
[root@localhost skel]# cat .bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions
[root@localhost skel]# cat .bash_logout
# ~/.bash_logout

 

 

九  數組

bash數組的特點:   1   沒有個數限制    2 可以跳躍賦值   3 所以可以表達式表示,如1+2      4  bash只支持一維數組

[root@localhost ~]# A[0]=5
[root@localhost ~]# A[1]=10
[root@localhost ~]# A[2]=28
[root@localhost ~]# A[3]="bash shell"

 [root@localhost ~]# echo $A
  5

[root@localhost ~]# echo $A[0]    看出跟上一句的區別了么?他走的是C語言的路子,讀取$A直接取得是數組首地址的值,如果要取數組剩余標的值,就需要下面的操作.也就是將整個數組包含小標用大括號括起來,表示一個整體變量,用$讀出
5[0]
[root@localhost ~]# echo $(A[0])    
bash: A[0]: 未找到命令...

[root@localhost ~]# echo ${A[0]}      #這里要注意一下,取數組值的時候,用到的是{}大括號
5
[root@localhost ~]# echo ${A[1+1]}
28
[root@localhost ~]# B={23 88 99 66}
bash: 88: 未找到命令...
[root@localhost ~]# B=(23 88 99 66)      #數組群體賦值的時候,用到的是()小括號。這點要注意
[root@localhost ~]# echo ${B[0]}
23

 正因為,shell數組沒有個數的限制,也就是說,不需要在使用數組的時候,首先要固定一下數組的長度,所以,他的自由度很大,可以給某一下標無限,跳躍似的賦值

取出所有數組元素 

用@符號來代替數組下標

[root@localhost ~]# echo ${A[@]}
5 10 28 bash shell

取得數組個數 

${#A[@]}的格式來取得數組的小標

[root@localhost ~]# echo ${#A[@]}
4

如果數組某個下標表示的值為字符串,還可以取得該字符串的長度

${#A[索引]}

如上例中,A【3】的值是bash shell。我們要想知道他的長度可以采用如下

[root@localhost ~]# echo ${#A[3]}
10

 

刪除數組和刪除變量函數都用的同一個命令。unset

如果要刪除整個數組可以用   unset A

如果要刪除數組中的某個賦值   unset A[3]   就會將bash shell 刪除。我們來試一下

[root@localhost ~]# unset A[3]              #將第三個數組值刪除
[root@localhost ~]# echo ${#A[3]}
0                          #數組長度變為0     
[root@localhost ~]# echo ${A[3]}     
                          #值變為空
[root@localhost ~]# echo ${A[@]}
5 10 28                      #打印所有變量的時候,也可以證明A[3]確實沒有了
[root@localhost ~]# unset A          #取消掉整個數組A
[root@localhost ~]# echo ${A[@]}        #整個數組A確實取消掉了。沒有數組元素了

[root@localhost ~]# 

 

十   Here Document 

bash 有一種特殊的程序區域。就是 Here Document,也可以用來設定變量。

語法為    命令   <<標記

[root@localhost ~]# wc -l << countline
> line1
> line2
> line3
> countline
3

Here Document也支持變量替換。在輸入的內容中,如果有變量,bash會在轉向前,將變量值進行替換

[root@localhost ~]# From="From: me@example.edu.cn"     #四個變量
[root@localhost ~]# To="To: you@example.edu.cn"
[root@localhost ~]# Subject="Subject: Hello world"
[root@localhost ~]# Msg="happy new year"
[root@localhost ~]# EM="20090310.txt"
[root@localhost ~]# cat > $EM <<here                  #進行轉向
> $From
> $To
> $Subject
> 
> $Msg
> here
[root@localhost ~]# cat 20090310.txt
From: me@example.edu.cn
To: you@example.edu.cn
Subject: Hello world

happy new year

 

利用Here Document做多行批注

bash中,只支持單行注釋,#來開頭

利用Here Document來做多行批注,可以用:來操作    : <<DO-NOTHING      

第一行,第二行,第三行 DO-NOTHING

利用Here Document夾帶私貨

書中就有一個夾帶私貨的例子。他是用Here Document寫了一個C程序,然后在編譯執行他,以便達到不可告人的目的,看看他是咋寫的

[root@localhost ShellScript]# vim create_prg.sh
#! /bin/bash

echo "正在產生hello.c。。。。"
echo
cat <<'EOF' >hello.c
#include <stdio.h>

int main()
{
        printf("Hello world!\n");
        return 0;
}
EOF

echo "編譯hello.c........"
echo 
#編譯Hello.c,並產生執行文件
gcc -o hello hello.c

#若編譯成功,則運行
if [ $? -eq 0 ]; then
        echo "執行 hello....."
        echo
        ./hello
else
        echo '執行失敗'
fi
"create_prg.sh" [新] 27L, 374C 已寫入                         
[root@localhost ShellScript]# sh create_prg.sh
正在產生hello.c。。。。

編譯hello.c........

執行 hello.....

Hello world!
[root@localhost ShellScript]# ls
20090310.txt  create_prg.sh  hello  hello.c

這樣就可以動態編寫c程序,動態執行。神不知鬼不覺。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM