[shell]>/dev/null 2>&1 的作用
放棄不會更舒服,只會萬劫不復
撐住,才有後來的一切 ---2017.8.26
我們在編寫shell的時候或者檢視系統中的指令碼程式時,經常會碰到題目中的文字資訊,很多人搞不清楚這是什麼意思(What),如何使用(How),用在何處(Where),何時要用(When),為什麼這麼用(Why)。
下面小編帶你逐步剖析一下,相信讀過本文後,你會豁然開朗,媽媽再也不用擔心我的學習了。
一、知識儲備
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
-
程式最大開啟檔案描述符數
使用ulimit -n檢視當前設定。使用ulimit -n 1000000進行臨時性設定。
要想永久生效,你可以修改/etc/security/limits.conf檔案,增加下面的行:
臨時性設定:echo 1000000 > /proc/sys/fs/file-max
永久設定:修改/etc/sysctl.conf檔案,增加fs.file-max = 1000000
* 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,如果沒有理解的話,請再回頭多看幾遍,相信你會有收穫的。
如果你覺得有所收穫並願意繼續學習的話,請掃碼關注:
你也可以轉賬讚賞喲
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29734436/viewspace-2146054/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 2>/dev/null和>/dev/null 2>&1和2>&1>/dev/null的區別devNull
- Difference between 2>&-, 2>/dev/null, |&, &>/dev/null, >/dev/null, 2>&1devNull
- Linux Shell 1>/dev/null 2>&1 含義LinuxdevNull
- shell 中的>/dev/null 2>&1 是什麼鬼?devNull
- shell指令碼中/dev/null 2>&1詳解指令碼devNull
- >/dev/null 2>&1devNull
- Shell標準輸出、標準錯誤 >/dev/null 2>&1devNull
- > /dev/null 2>&1 什麼意思?devNull
- Shell指令碼中的 /Dev/Null 用途指令碼devNull
- Linux下" >/dev/null 2>&1 "相關知識說明LinuxdevNull
- /dev/zero和/dev/null的區別devNull
- 重建/dev/null檔案devNull
- [轉] linux下 /dev/null與/dev/zero的區別LinuxdevNull
- /dev/null解決辦法devNull
- /dev/null和標準*使用devNull
- 『忘了再學』Shell基礎 — 2、Shell的作用與分類
- Shell重定向&>file、2>&1、1>&2的區別
- 關於/dev/null和/dev/zero兩個檔案裝置devNull
- BEA dev2dev 線上dev
- Linux shell中2>&1的含義Linux
- shell 中的export作用(轉載)Export
- shell中變數$#,$@,$0,$1,$2的含義變數
- 關於ResultFilter類中NULL_INT的作用????FilterNull
- Shell變數的作用域問題變數
- linux shell指令碼中 =~ 的作用Linux指令碼
- 理解 shell 指令碼中的常見用法: 2>&1指令碼
- [Shell] Input null到檔案中的兩個方法Null
- 關於 /dev/null 差點直播吃鞋的一個小問題devNull
- 【Postopia Dev Log】Day 2dev
- PHP7 ?? 與 ?: 的作用和區別(null合併運算子, null條件運算子)PHPNull
- 【Postopia Dev Blog】day 1dev
- mount.ocfs2: Transport endpoint is not connected while mounting /dev/emcpowera1Whiledev
- R1-007 Shell變數簡介2變數
- 【NULL】Where子句中=1 與!=1UNION後的結果是全集麼?——NULL小夥惹的禍Null
- /dev/null Read-only file system 系統無法啟動薦devNull
- 了不起的 “filter(NULL IS NOT NULL)”FilterNull
- oracleasm createdisk : Device '/dev/emcpowera1 is not a partitionOracleASMdev
- Shell程式設計-shell變數1程式設計變數