[shell]>/dev/null 2>&1 的作用

dbasdk發表於2017-10-17

 

放棄不會更舒服,只會萬劫不復

撐住,才有後來的一切 ---2017.8.26

我們在編寫shell的時候或者檢視系統中的指令碼程式時,經常會碰到題目中的文字資訊,很多人搞不清楚這是什麼意思(What),如何使用(How),用在何處(Where),何時要用(When),為什麼這麼用(Why)。

下面小編帶你逐步剖析一下,相信讀過本文後,你會豁然開朗,媽媽再也不用擔心我的學習了[shell]>/dev/null 2>&1 的作用

一、知識儲備

1、檔案描述符

Linux shell執行命令時,每個程式都和三個開啟的檔案相聯絡,並使用檔案描述符來引用這些檔案。由於檔案描述符不容易記憶,shell同時也給出了相應的檔名


檔案 檔案描述符
輸入檔案—標準輸入 0(預設是鍵盤,為0時是檔案或者其他命令的輸出)
輸出檔案—標準輸出 1(預設是螢幕,為1時是檔案)
錯誤輸出檔案—標準錯誤 2(預設是螢幕,為2時是檔案)

這裡對檔案描述符作一下引申:

我們在進行應用的測試或者運維時經常會碰到“Too many open files”的提示,這說明你操作的檔案控制程式碼已經超過了系統的引數配置,需要進行相應修改,下面簡單介紹一下linux與solaris系統下檔案控制程式碼的修改方式:

1.1、Linux平臺

A、檢視配置

透過命令:ulimit -n 進行檢視系統當前值;

檢視當前系統使用的開啟檔案描述符數,可以使用下面的命令:

[root@localhost ~]# cat /proc/sys/fs/file-nr

1632 0 1513506

  • 第一個數表示當前系統已分配使用的開啟檔案描述符數

  • 第二個數為分配後已釋放的(目前已不再使用)

  • 第三個數等於file-max。

B、修改配置

Linux核心本身有檔案描述符最大值的限定,你可以根據需要更改:

  • 系統最大開啟檔案描述符數:/proc/sys/fs/file-max

  • 臨時性設定:echo 1000000 > /proc/sys/fs/file-max

    永久設定:修改/etc/sysctl.conf檔案,增加fs.file-max = 1000000

  • 程式最大開啟檔案描述符數
    使用
    ulimit -n檢視當前設定。使用ulimit -n 1000000進行臨時性設定。
    要想永久生效,你可以修改
    /etc/security/limits.conf檔案,增加下面的行:

                   * hard nofile 1000000

               * soft nofile 1000000

               root hard nofile 1000000

               root soft nofile 1000000

(對於安裝過oracle資料庫的各位,上面的資訊想必不會陌生)

還有一點要注意的就是hard limit不能大於/proc/sys/fs/nr_open,因此有時你也需要修改nr_open的值。

執行echo 2000000 > /proc/sys/fs/nr_open

C、總結

  • 所有程式開啟的檔案描述符數不能超過/proc/sys/fs/file-max

  • 單個程式開啟的檔案描述符數不能超過user limit中nofile的soft limit

  • nofile的soft limit不能超過其hard limit

  • nofile的hard limit不能超過/proc/sys/fs/nr_open

1.2、Solaris平臺

程式能夠開啟的最大檔案控制程式碼數決定了每個程式能夠同時開啟的檔案數量。Solaris10上預設值是256,對於某些應用而言,預設值太小,需要手工修改。

A、檢視配置

有兩種方式,一是使用ulimit命令,二是使用prctl命令;

a)、ulimit命令

oracle@hisdb:~ $>ulimit -a 

core file size          (blocks, -c) unlimited 

data seg size           (kbytes, -d) unlimited 

file size               (blocks, -f) unlimited 

open files                      (-n) 256 

pipe size            (512 bytes, -p) 10 

stack size              (kbytes, -s) 10240 

cpu time               (seconds, -t) unlimited 

max user processes              (-u) 11445 

virtual memory          (kbytes, -v) unlimited

open files表示程式能夠開啟的最大檔案控制程式碼數量。

b)、prctl命令

oracle@hisdb:~ $>prctl -i process $$ 

process: 1079: -bash 

NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT

…… 

process.max-file-descriptor 

        basic             256       -   deny                              1079 

        privileged      65.5K       -   deny                                 - 

        system          2.15G     max   deny                                 -

…… 

process.max-file-descriptor表示程式能夠開啟的最大檔案控制程式碼數,其中basic表示軟限制,privileged表示硬限制。非root使用者可以在硬限制的範圍內自行調整軟硬限制值。

B、修改配置

修改此引數通常有以下幾種方法:

1)、使用ulimit命令或plimit命令修改

ulimit命令只能修改當前SHELL及其子程式的設定,設定後立即生效,一旦當前SHELL退出設定即失效。-S引數用於設定軟限制,-H引數用於設定硬限制。

  • 設定軟限制:

oracle@hisdb:~ $>ulimit -S -n 1024 

oracle@hisdb:~ $>ulimit -a 

core file size          (blocks, -c) unlimited 

data seg size           (kbytes, -d) unlimited 

file size               (blocks, -f) unlimited 

open files                      (-n) 1024 

pipe size            (512 bytes, -p) 10 

stack size              (kbytes, -s) 10240 

cpu time               (seconds, -t) unlimited 

max user processes              (-u) 11445 

virtual memory          (kbytes, -v) unlimited

oracle@hisdb:~ $>prctl -i process $$ 

process: 1079: -bash 

NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT

……

process.max-file-descriptor 

        basic           1.02K       -   deny                              1079 

        privileged      65.5K       -   deny                                 - 

        system          2.15G     max   deny                                 -

……

oracle@hisdb:~ $>ulimit -S -n 65536 

oracle@hisdb:~ $>ulimit -a 

core file size          (blocks, -c) unlimited 

data seg size           (kbytes, -d) unlimited 

file size               (blocks, -f) unlimited 

open files                      (-n) 65536 

pipe size            (512 bytes, -p) 10 

stack size              (kbytes, -s) 10240 

cpu time               (seconds, -t) unlimited 

max user processes              (-u) 11445 

virtual memory          (kbytes, -v) unlimited 

oracle@hisdb:~ $>ulimit -S -n 65537 

-bash: ulimit: open files: cannot modify limit: Invalid argument

軟限制只能在privileged的值以下調整,此例中所能調整的最大值是65536。

  • 設定硬限制

oracle@hisdb:~ $>ulimit -a 

core file size          (blocks, -c) unlimited 

data seg size           (kbytes, -d) unlimited 

file size               (blocks, -f) unlimited 

open files                      (-n) 256 

pipe size            (512 bytes, -p) 10 

stack size              (kbytes, -s) 10240 

cpu time               (seconds, -t) unlimited 

max user processes              (-u) 11445 

virtual memory          (kbytes, -v) unlimited

ulimit命令中open files顯示的是軟限制,可以用prctl命令顯示硬限制,即privileged值。

oracle@hisdb:~ $>prctl -i process $$ 

process: 1139: -bash 

NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT

……

process.max-file-descriptor 

        basic             256       -   deny                              1139 

        privileged      65.5K       -   deny                                 - 

        system          2.15G     max   deny                                 -

……

oracle@hisdb:~ $>ulimit -H -n 65537 

-bash: ulimit: open files: cannot modify limit: Not owner 

oracle@hisdb:~ $>ulimit -H -n 32768 

oracle@hisdb:~ $>ulimit -a 

core file size          (blocks, -c) unlimited 

data seg size           (kbytes, -d) unlimited 

file size               (blocks, -f) unlimited 

open files                      (-n) 256 

pipe size            (512 bytes, -p) 10 

stack size              (kbytes, -s) 10240 

cpu time               (seconds, -t) unlimited 

max user processes              (-u) 11445 

virtual memory          (kbytes, -v) unlimited

oracle@hisdb:~ $>prctl -i process $$ 

process: 1139: -bash 

NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT

process.max-file-descriptor 

        basic             256       -   deny                              1139 

        privileged      32.8K       -   deny                                 - 

        system          2.15G     max   deny                                 -

非root使用者調整硬限制時只能往小調,不能往大調。

2)、修改/etc/system引數

在Solaris10上,這種方法已經不建議使用,但這種方式仍然有效。/etc/system中設定引數是全域性有效的,即所有使用者均會受影響。並且設定後,需要重啟系統才能生效。

設定方法是在/etc/system檔案中增加以下兩個引數,然後重啟系統。

set rlim_fd_cur=1024

set rlim_fd_max=65535


  • 以下是兩個引數的說明:

  • rlim_fd_max (硬限制) 

Description : Specifies the “hard” limit on file descriptors that a single process might have open.Overriding this limit requires superuser privilege. 

Data Type : Signed integer 

Default : 65,536 

Range : 1 to MAXINT 

Units : File descriptors 

Dynamic? : No 

Validation : None 

When to Change : When the maximum number of open files for a process is not enough. Other limitations in system facilities can mean that a larger number of file descriptors is not as useful as it might be. For example: 

■ A 32-bit program using standard I/O is limited to 256 file descriptors. A 64-bit program using standard I/O can use up to 2 billion descriptors. Specifically, standard I/O refers to the 

stdio(3C) functions in libc(3LIB). 

■ select is by default limited to 1024 descriptors per fd_set. For more information, see select(3C). Starting with the Solaris 7 release, 32-bit application code can be recompiled with a larger fd_set size (less than or equal to 65,536). A 64-bit application uses an fd_set size of 65,536, which cannot be changed.

An alternative to changing this on a system wide basis is to use the plimit(1) command. If a parent process has its limits changed by plimit, all children inherit the increased limit. This alternative is useful for daemons such as inetd.

Commitment Level : Unstable 

ChangeHistory : For information, see “rlim_fd_max (Solaris 8 Release)” on page 184.

 

  • rlim_fd_cur (軟限制) 

Description : Defines the “soft” limit on file descriptors that a single process can have open. A process might adjust its file descriptor limit to any value up to the “hard” limit defined by rlim_fd_max by using the setrlimit() call or by issuing the limit command in whatever shell it is running. You do not require superuser privilege to adjust the limit to any value less than or equal to the hard limit. 

Data Type : Signed integer 

Default : 256 

Range : 1 to MAXINT 

Units : File descriptors 

Dynamic? : No 

Validation : Compared to rlim_fd_max. If rlim_fd_cur is greater than rlim_fd_max, rlim_fd_cur is reset to rlim_fd_max. 

When to Change : When the default number of open files for a process is not enough. Increasing this value means only that it might not be necessary for a program to use setrlimit to increase the maximum number of file descriptors available to it. 

Commitment Level : Unstable

3)、project命令

project是Solaris10新增加的特性,可以透過設定project引數為一個使用者或一組使用者設定引數值。設定後可立即生效。

以下是設定示例:

root@hisdb:/ #>projadd user.test  (建立project user.test) 

root@hisdb:/ #>id -p test

uid=100(test) gid=1(other) projid=100(user.test)   (test使用者屬於project user.test)

root@hisdb:/ #>projmod -a -K "process.max-file-descriptor=(basic,65537,deny)" user.test

root@hisdb:/ #>projmod -a -K "process.max-file-descriptor=(priv,65538,deny)" user.test

root@hisdb:/ #>grep 'user.test' /etc/project 

user.test:100::::process.max-file-descriptor=(basic,65537,deny),(priv,65538,deny)

設定basic和privilege值分別為65537和65538,越過/etc/system中的最大硬限制

root@hisdb:/ #>tail -2 /etc/system 

set rlim_fd_cur=1024 

set rlim_fd_max=65535

root@hisdb:/ #>plimit $$ 

1041:   -bash 

   resource              current         maximum 

  time(seconds)         unlimited       unlimited 

  file(blocks)          unlimited       unlimited 

  data(kbytes)          unlimited       unlimited 

  stack(kbytes)         10240           unlimited 

  coredump(blocks)      unlimited       unlimited 

  nofiles(descriptors)  1024            65535 

  vmemory(kbytes)       unlimited       unlimited

root使用者的結果只受/etc/system裡引數的影響,而不受project user.test影響,root使用者不屬於此project. 

root@hisdb:/ #>su - test

Oracle Corporation      SunOS 5.10      Generic Patch   January 2005 

test@hisdb:~ $>plimit $$ 

1091:   -bash 

   resource              current         maximum 

  time(seconds)         unlimited       unlimited 

  file(blocks)          unlimited       unlimited 

  data(kbytes)          unlimited       unlimited 

  stack(kbytes)         10240           unlimited 

  coredump(blocks)      unlimited       unlimited 

  nofiles(descriptors)  65535           65535 

  vmemory(kbytes)       unlimited       unlimited 

test@hisdb:~ $>id -p 

uid=100(test) gid=1(other) projid=100(user.test)

使用者test當前值和最大值都是65535,而project user.test裡設定的值分別是65537和65538,使用者結果與project設定值不一致,這是因為project中設定的值超過了/etc/system裡設定的最大硬限制數是65535,此時系統自動將使用者結果調整為/etc/system中設定的最大硬限制數。

root@hisdb:/ #>projmod -s -K "process.max-file-descriptor=(basic,32767,deny),(priv,32768,deny)" user.test

root@hisdb:/ #>plimit $$ 

1041:   -bash 

   resource              current         maximum 

  time(seconds)         unlimited       unlimited 

  file(blocks)          unlimited       unlimited 

  data(kbytes)          unlimited       unlimited 

  stack(kbytes)         10240           unlimited 

  coredump(blocks)      unlimited       unlimited 

  nofiles(descriptors)  1024            65535 

  vmemory(kbytes)       unlimited       unlimited

root使用者未受project user.test調整影響。 

root@hisdb:/ #>su - test

Oracle Corporation      SunOS 5.10      Generic Patch   January 2005 

test@hisdb:~ $>plimit $$ 

1099:   -bash 

   resource              current         maximum 

  time(seconds)         unlimited       unlimited 

  file(blocks)          unlimited       unlimited 

  data(kbytes)          unlimited       unlimited 

  stack(kbytes)         10240           unlimited 

  coredump(blocks)      unlimited       unlimited 

  nofiles(descriptors)  32767           32768 

  vmemory(kbytes)       unlimited       unlimited

使用者test當前值和最大值均與project user.test中的設定一致。

注:

如果在系統裡同時設定/etc/system和project裡的引數時要注意以下幾點:

1. /etc/system的設定是全域性設定,會影響所有使用者,而project的設定僅影響屬於此project的使用者。

2. /etc/system的設定需要重啟系統才能生效,而project的設定立即生效(新程式)。

3. /etc/system的硬限制值是所有使用者的最大限制值。如果project中的設定值超過了/etc/system的硬限制值,則project設定無效,相應使用者值會被設定為/etc/system的硬限制值。

1.3、HPUX平臺

A、檢視配置

透過命令:ulimit -a

B、修改配置

1)、透過sam(smh)命令

2)、設定HP-UX的核心環境,對核心環境進行管理。但修改後不能立即對核心引數進行管理。因為系統會向boot.config讀出引數,所以只有移走boot.config,然後再用getkinfo重建boot.config檔案。在SAM--》Kernel configuration--> Parameter會自動執行getkinfo 命令。

  • 先修改/usr/conf/master.d/core-hpux: 

*range maxfiles<=60000 

*range maxfiles_lim<=60000 

  • 把/var/sam/boot.config檔案mv成boot.config.bak 

    mv /var/sam/boot.config /var/sam/boot.config.bak 

  • 然後執行:/usr/sam/lbin/getkinfo -b 

1.4、AIX平臺

A、檢視配置

透過命令:ulimit -a

B、修改配置

1)、透過工具smit進行修改

2)、修改檔案:/etc/security/limits

2、檔案重定向

2.1、輸出重定向

Command > filename 把標準輸出重定向到一個新檔案中
Command >> filename 把標準輸出重定向到一個檔案中(追加)
Command > filename 把標準輸出重定向到一個檔案中
Command > filename 2>&1 把標準輸出和錯誤一起重定向到一個檔案中
Command 2 > filename 把標準錯誤重定向到一個檔案中
Command 2 >> filename 把標準輸出重定向到一個檔案中(追加)
Command >> filename2>&1 把標準輸出和錯誤一起重定向到一個檔案(追加)

2.2、輸入重定向

Command < filename > filename2 Command命令以filename檔案作為標準輸入,以filename2檔案作為標準輸出
Command < filename Command命令以filename檔案作為標準輸入
Command << delimiter  從標準輸入中讀入,知道遇到delimiter分界符

2.3、繫結重定向

Command >&m 把標準輸出重定向到檔案描述符m中
Command < &- 關閉標準輸入
Command 0>&- 同上

3、/dev/null介紹

是個黑洞裝置,它丟棄一切寫入其中資料,空裝置通常被用於丟棄不需要的輸出流。記得當年用windows時候,有個類似的裝置:NUL ,跟這個功能一樣。任何寫入該裝置資料都會被丟棄掉。從這個裡面讀取資料返回是空。將一些不用內容經常傳送給這個裝置,丟棄不需要的資料。

二、>/dev/null 2>&1剖析

前面囉嗦了太多,各位是不是有點不耐煩了,不要著急,如果你仔細閱讀了前面的基礎知識,相信這個問題就迎刃而解了:

我們把題目分解開來如下:

  • /dev/null 代表空裝置檔案 

  • > 代表重定向到哪裡,例如:echo "123" > /home/123.txt 

  • 1 表示stdout標準輸出,系統預設值是1,所以">/dev/null"等同於"1>/dev/null" 

  • 2 表示stderr標準錯誤 

  • & 表示等同於的意思,2>&1,表示2的輸出重定向等同於1

那麼本文標題的正確理解為: 

  • 1>/dev/null 首先表示標準輸出重定向到空裝置檔案,也就是不輸出任何資訊到終端,說白了就是不顯示任何資訊。 

  • 2>&1 接著,標準錯誤輸出重定向等同於 標準輸出,因為之前標準輸出已經重定向到了空裝置檔案,所以標準錯誤輸出也重定向到空裝置檔案。 

各位看官,不知你理解了沒有,你應該明白What/How/Where/When/Why,如果沒有理解的話,請再回頭多看幾遍,相信你會有收穫的。


如果你覺得有所收穫並願意繼續學習的話,請掃碼關注:

[shell]>/dev/null 2>&1 的作用[shell]>/dev/null 2>&1 的作用[shell]>/dev/null 2>&1 的作用你也可以轉賬讚賞喲[shell]>/dev/null 2>&1 的作用[shell]>/dev/null 2>&1 的作用[shell]>/dev/null 2>&1 的作用

          

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29734436/viewspace-2146054/,如需轉載,請註明出處,否則將追究法律責任。

相關文章