I am writing a bash script and encountered a warning message when using the tee command. I have reduced my code to this line:
echo "hi" | tee >(tee)
It works well and "hi" is printed out. But it also produces this warning:
tee: /dev/fd/63: Not a directory
I get this warning only in Cygwin and not under Linux.
My question is why this warning is produced? I think the command is clean and working well?
Related
My working directory is as follows:
MyWorkDirectory
└── test
The file "test" contains a line of information:
1:2:3:4:5
When I use the following command:
cat test foo
the output is as follows:
1:2:3:4:5
cat: foo: No such file or directory
I want to ignore STDOUT and only deal with STDERR, and I want to use the cut command to get the third STDERR segment separated by the ":",So I tried the following command:
cat test foo 2>&1 1>/dev/null | cut -d ':' -f 3
I think the output here should be as follows:
No such file or directory
However, there are many different outputs here:
1、
1
No such file or directory
2、
No such file or directory
3
3、
2
4、
...
Why are these outputs generated? What commands should I use if I want to achieve my goal?
The issue here is "multiple redirect".
The reason this can not be reproduced on Ubuntu, is because Ubuntu (like many Debian based Linux distros) uses Ash or Bash shell by default, while recent MacOS version switched to using ZSH.
ZSH on Ubuntu will give similar result to what you are getting.
Apparently, using both redirect > and pipe | causes ZSH to split you stderr similar to tee command.
This post shows a solution to the problem:
https://unix.stackexchange.com/questions/265061/how-can-i-pipe-only-stderr-in-zsh
Specifically, you need to close stdout before redirecting it to /dev/null to prevent the split:
cat test foo 2>&1 >&- > /dev/null | cut -d ':' -f 3
This works with ZSH on Ubuntu, and should work on Mac OS.
If it does not, check the linked post for enabling mult_ios option in your shell.
I have a bash script, which when it's finished running, it going to write some files into a directory.
It prints a lot of warnings, which slows down the process, I'm looking for an effective way to prevent printing the warnings in the shell.
I added 2> /dev/null to end of my command at mybash.sh:
#!/bin/bash
command -f file 2> /dev/null
the original command:
java -mx28000M -jar ChromHMM.jar BinarizeBam CHROMSIZES/hg19.txt /Volumes/Control/ /primary_bam_files/FCX/Control/Marks_Run1.txt /Volumes/Control/output1/
When I run my mybash.sh, it will write 20 different output files in a directory.
However, when I use 2>/dev/null, it does not print any warning in the shell which is great but also does not write anything in the output directory which in principle should those 20 files.
Can anyone help me to solve this problem?
On Linux I'm using "tee" to capture the output of "source" command and print it to output log file, but failed. The command I'm using is like this:
source ./my_run.sh 2>&1 | tee -i my_run_log
The intention of my_run.sh is to "make" some compile job, as well as some routine jobs like cd, rm and svn update. The content of my_run.sh is like follows:
make clean
cd ..
rm ./xxx
svn up -r 166
cd ./aaa/
sed -i -e ......
make compile
make run
However, when I run it the "tee" just does NOT work, and do NOT give me the log file at all. In order to verify that the entire environment is good, I did a simpler test with:
ll 2>&1 | tee -i log
and in this simpler scenario the "tee" works perfectly fine and prints out "log" as I expected.
Can anyone help me find out where my problem is?
btw,
I'm working on Red Hat Linux (Release 5.9), using bash shell.
Thanks in advance!
SOME MORE COMMENTS:
I did some more tests and found that as long as the my_run.sh script has got "make xxx" stuffs in it, then "tee" will fail. Seems like tee does NOT like make. Any solutions?
Problem solved; many thanks goes to #thatotherguy in leading me to the solution. The log output was actually deleted by the make clean process. After fixing the clean stuff in the makefile, everything is good.
I am aware that for redirecting standard error and output to file I have to do:
make > & ! output.txt
Note I use ! to overwrite the file. But How can I redirect standard error to file and leave standard output to screen? Or even better having both error and output on file but also output on screen, so I can see how my compiling is progressing?
I tried:
make 2>! output.txt
but it gives me an error.
Note that > it enough to overwrite the file. You can use the tail -f command to see the output on screen if it is redirected to a file:
$(make 1>output.txt 2>error.txt &) && tail -f output.txt error.txt
You can do this simply with pipe into tee command. The following will put both stdout and stderr into a file and also to the terminal:
make |& tee output.txt
Edit
Explanation from GNU Bash manual, section 3.2.2 Pipelines:
If ‘|&’ is used, command1’s standard error, in addition to its
standard output, is connected to command2’s standard input through the
pipe; it is shorthand for 2>&1 |. This implicit redirection of the
standard error to the standard output is performed after any
redirections specified by the command.
You are reading bash/sh documentation and using tcsh. tcsh doesn't have any way to redirect just stderr. You might want to switch to one of the non-csh shells.
I'm building an opensource project from source (CPP) in Linux. This is the order:
$CFLAGS="-g Wall" CXXFLAGS="-g Wall" ../trunk/configure --prefix=/somepath/ --host=i386-pc --target=i386-pc
$make
While compiling I'm getting lot of compiler warnings. I want to start fixing them. My question is how to capture all the compiler output in a file?
$make > file is not doing the job. It's just saving the compiler command like g++ -someoptions /asdf/xyz.cpp I want the output of these command executions.
The compiler warnings happen on stderr, not stdout, which is why you don't see them when you just redirect make somewhere else. Instead, try this if you're using Bash:
$ make &> results.txt
The & means "redirect stdout and stderr to this location". Other shells often have similar constructs.
In a bourne shell:
make > my.log 2>&1
I.e. > redirects stdout, 2>&1 redirects stderr to the same place as stdout
Lots of good answers so far. Here's a frill:
$ make 2>&1 | tee filetokeepitin.txt
will let you watch the output scroll past.
The output went to stderr. Use 2> to capture that.
$make 2> file
Assume you want to hilight warning and error from build ouput:
make |& grep -E "warning|error"
Based on an earlier reply by #dmckee
make | tee makelog.txt
This gives you real-time scrolling output while compiling, and simultaneously write to the makelog.txt file.
Try make 2> file. Compiler warnings come out on the standard error stream, not the standard output stream. If my suggestion doesn't work, check your shell manual for how to divert standard error.
From http://www.oreillynet.com/linux/cmd/cmd.csp?path=g/gcc
The > character does not redirect the
standard error. It's useful when you
want to save legitimate output without
mucking up a file with error messages.
But what if the error messages are
what you want to save? This is quite
common during troubleshooting. The
solution is to use a greater-than sign
followed by an ampersand. (This
construct works in almost every modern
UNIX shell.) It redirects both the
standard output and the standard
error. For instance:
$ gcc invinitjig.c >& error-msg
Have a look there, if this helps:
another forum
In C shell
- The ampersand is after the greater-than symbol
make >& filename
It is typically not what you want to do. You want to run your compilation in an editor that has support for reading the output of the compiler and going to the file/line char that has the problems. It works in all editors worth considering. Here is the emacs setup:
https://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation.html