您好,登錄后才能下訂單哦!
放棄不會更舒服,只會萬劫不復
撐住,才有后來的一切 ---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
臨時性設置: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,如果沒有理解的話,請再回頭多看幾遍,相信你會有收獲的。
如果你覺得有所收獲并愿意繼續學習的話,請掃碼關注:
你也可以轉賬贊賞喲
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。