半个IT人的个人空间

半个IT人,一直在路上

  • 博客访问: 58733
  • 博文数量: 1
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-27 09:15
  • 认证徽章:
个人简介

个人QQ:84096791 微信:semiter1982 个人微信公众号:半个IT人 个人博客:http://blog.itpub.net/23149897/

ITPUB论坛APP

ITPUB论坛APP



APP发帖 享双倍积分

文章分类

全部博文(1)

文章存档

2017年(1)

微信关注

IT168企业级官微



微信号:IT168qiye



系统架构师大会



微信号:SACC2013

订阅
热词专题
[shell]>/dev/null 2>&1 的作用 2017-08-27 10:17:18

分类: Linux

 

放弃不会更舒服,只会万劫不复

撑住,才有后来的一切 ---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,如果没有理解的话,请再回头多看几遍,相信你会有收获的。


如果你觉得有所收获并愿意继续学习的话,请扫码关注:

你也可以转账赞赏哟

          

阅读(1251) | 评论(0) | 转发(1) |
0

上一篇:没有了

下一篇:没有了

给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册