It seems quite straightforward.
romano@RRyS:~$ size=$(ls -l /var/spool | wc -c)
romano@RRyS:~$ echo $size
476
The shell syntax $(command)
executes command
, and returns the standard output: just save it in a variable.
Your command:
ls -l /var/spool | wc -c > size
will create a file named size
in the current directory (containing the number and a newline).
From bash manual section 3.6.2:
...if it does exist it is truncated to zero size.
Redirection with > file
always truncates file before executing command, which means contents are erased regardless of the output; the actual writing to file will take place if there is an actual output (most notably observed with the lack of write()
call in strace -f -e open,dup2,write bash -c 'true > out2.txt'
) and if no further error occurs.
Therefore, everything works properly, as per specifications, and the wording is correct. In fact this behavior is specified by POSIX Shell Command Language specifications and is supported by all POSIX-compliant shells, including ksh
and dash
(aka Ubuntu's /bin/sh
, see the related question).
On the system level, redirection is performed by dup family of system calls, which is why redirection is formally called duplicating file descriptors and is most prominent when we perform the >/dev/null 2&>1
type of redirection.
It can be observed with strace
command in the following example of successful and failed command. Note how the files are opened with O_CREAT|O_TRUNC
flag.
$ strace -f -e open,dup2,write bash -c 'nocommand > out.txt;echo "foobar" > out2.txt'
...
strace: Process 9633 attached
[pid 9633] open("out.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
[pid 9633] dup2(3, 1) = 1
...
...
[pid 9633] write(2, "bash: nocommand: command not fou"..., 35bash: nocommand: command not found
) = 35
[pid 9633] +++ exited with 127 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=9633, si_uid=1000, si_status=127, si_utime=0, si_stime=0} ---
open("out2.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1) = 1
write(1, "foobar\n", 7) = 7
dup2(10, 1) = 1
+++ exited with 0 +++
Best Answer
IMHO it would be more elegant to use the presence / value of the variable to conditionally close the file descriptors e.g.
then
but
If you really want to toggle the redirection, you could consider creating a shell function that duplicates the file descriptor(s) before closing them, and then restores the duplicates to re-enable the original streams e.g.
Result: