23

I want to know if there is a built-in BASH command that prints some text on stderr, just like the echo command that prints text on stdout. I don't want to use temporary io-redirection. I use a built-in command to generate an error on stderr such as ls --asdf (ls: unrecognized option '--asdf') but I want something neater.

Edit ----

Actually I am trying to demonstrate stderr/stdout redirection, and my example looks like:

sh test.sh >test-out.txt 2>test-err.txt

For clarity, I want to keep the test.sh file as simple and clean as possible, this means avoiding > operator inside the file.

Salman A
  • 262,204
  • 82
  • 430
  • 521

6 Answers6

19

No one has mentioned this but you can also do this:

echo An error message > /dev/stderr

It's possibly more readable than >&2 but I guess that depends who you are.

nic ferrier
  • 1,573
  • 13
  • 14
17

echo something >&2 is the correct way to do what you want.

However...

This will create a little program that will echo its arguments to stderr:

gcc -o echoerr -x c - <<'EOF'
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char **argv) {
    int i;
    for (i = 1; i < argc; i++) {
        fprintf(stderr, "%s ", argv[i]);
    }
    fprintf(stderr, "\n");
    exit(0);
}
EOF

You can use it like this:

$ ./echoerr this is an error message
this is an error message
$ ./echoerr this is an error message 2>error.out
$ cat error.out
this is an error message
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 1
    You may want to add: `if (argc > 1) fprintf (stderr, "\n");` to prevent a stray newline to `stderr` when no input given. – David C. Rankin Aug 18 '14 at 21:59
  • @DavidC.Rankin: I think that's a good idea. However, as it stands, it outputs a newline when no arguments are present in the same way that `echo` does. – Dennis Williamson Aug 18 '14 at 22:34
  • Yes, I saw that as well, but I figured if we were doing something custom, we could make it work a litter better :) I tested both ways, and I like suppressing the newline in the case of no input. Others may like the blank line. – David C. Rankin Aug 19 '14 at 00:31
6

No builtin, you could use:

function echo-err { echo "$@" >&2; }
Jürgen Hötzel
  • 18,997
  • 3
  • 42
  • 58
4

You could also make an alias.

alias echoerr='echo >&2'
Chris Cooper
  • 17,276
  • 9
  • 52
  • 70
  • 2
    This won't work for `echoerr foo 2> test-err.txt` since the alias is expanded then both redirections are set up at the same time and the second one doesn't know the first one has been set up yet. Aliases should be avoided in scripts - use functions instead. – Dennis Williamson Aug 18 '14 at 22:41
1

Just a sidenote: If you like to demonstrate bash, you should use bash, not sh:

sh test.sh >test-out.txt 2>test-err.txt
bash test.sh >test-out.txt 2>test-err.txt

Even if sh is a link to bash on your system, it will check how it was called (arg0) and treat sh-calls like an invocation

bash --posix 

which leads to sometimes subtile different behaviour. A common mistake, like shebangs #/bin/sh 'but it did work in the shell' (which was /bin/bash).

user unknown
  • 35,537
  • 11
  • 75
  • 121
0

In general, I think that there is not really a difference between 'temporary io-redirection' and the thing you want. stderr is a file descriptor like any other, and any builtin that does what you want would just be doing the same thing internally that you do by redirecting echo as Jurgen suggested above, namely, calling write() on it.

Personman
  • 2,324
  • 1
  • 16
  • 27