Getting an ambiguous redirect error
Bash can be pretty obtuse sometimes.
The following commands all return different error messages for basically the same error:
$ echo hello >
bash: syntax error near unexpected token `newline`
$ echo hello > ${NONEXISTENT}
bash: ${NONEXISTENT}: ambiguous redirect
$ echo hello > "${NONEXISTENT}"
bash: : No such file or directory
Adding quotes around the variable seems to be a good way to deal with the "ambiguous redirect" message: You tend to get a better message when you've made a typing mistake -- and when the error is due to spaces in the filename, using quotes is the fix.
How to solve this ambiguous redirect error
the most logical way of doing it is to redirect from inside the loop instead, but not directly (thanks 123 for the comment: file cannot be input and output as the same time, maybe here it could work since windows loop seems to work, but let's not take useless risks...)
for f in ./*.fa ; do ./anchor $f -d ./ > /tmp/something; cat /tmp/something >> $f; done
BTW: I wouldn't dare trying to explain what your original code does, is f
defined/when $f
is evaluated (before or after entering the for
loop).
My guess is that $f
just not evaluated and considered as $f
literally, which confuses bash
.
At any rate, it's incorrect.
EDIT: the windows version
for %F in ("*.fa") do anchor %F -d ./ >> %%F
does the redirection inside the loop (unlike your unix attempt), and it's really surprising that it works because of windows file locking...
What could happen (not sure) is that windows doesn't try to append to the file before something is issued on standard output, and at that moment, the program has closed the file as input.
Ambiguous redirect error in shell scripting when creating file name with date
The $(date)
in your example produces a timestamp with blanks. You might either use your function ($(timestamp)
) instead, or quote the whole target filename (or both):
echo bla >> "/home/pi/logs/temperature_log_$(timestamp).txt"
And it is best to actually evaluate the timestamp in the filename only before the loop, otherwise you get a new file every second or minute:
# %F: full date; same as %Y-%m-%d
logfile = "/home/pi/logs/temperature_log_$(date +%F).txt"
echo "Temperature Log_$(date)" > "$logfile" # overwrite if started 2 times a day
for i in {1..5}
do
temp=$(/opt/vc/bin/vcgencmd measure_temp)
temp=${temp:5:9}
echo "${temp} $(timestamp)" >> "$logfile"
sleep 1
done
Ambiguous redirect error when executing a script
The first line of your error message is telling you that you have a carriage return at the end of your line.
You have several ways to solve the problem:
Make sure your script has unix-style line endings (eg. dos2unix)
Add a statement terminator to the end of each command, such as:
; #
Linux command ambiguous redirect
The I/O redirection operators <
, >
, etc. all only take one word as their argument, and use that as a filename. Anything else is considered part of the command line.
So when you run this:
cat ../header.txt > find -name *.c
It's exactly the same as this:
cat ../header.txt -name *.c > find
That's probably not going to do anything useful.
Another problem: your *.c
isn't escaped or quoted, so bash will expand it rather than passing it to find
.
You can do what you seem to want with tee
, which accepts any number of arguments:
cat ../header.txt | tee *.c
And then you don't even need cat
any more, really.
tee *.c < ../header.txt
Of course, you could just as well do this with cp
. Perhaps you meant to append to these files? If so, pass -a
to tee
as well.
Interesting trivia: zsh and some other shells will let you have multiple >
operators, which works just like tee
. (Multiple <
is also allowed and works like cat
.)
cat infile > outfile1 > outfile2
But you have to actually list every file individually, so you can't use this shortcut with a glob like *.c
.
Ambiguous redirect error with echo
You don't need to touch
if you are going to overwrite the files immediately anyway.
echo "." | tee a{1..9}.txt >/dev/null
If you want to overwrite all existing files matching a specific wildcard expression, you can use that as the argument to tee
, of course:
echo "." | tee *.txt >/dev/null
You generally cannot redirect to a wildcard expression unless you are sure that it expands to exactly one existing file.
Ambiguous redirect or : : No such file or directory trying to save while loop's output to file
Try this:
#!/bin/bash
mkdir -p ./err_logs
mkdir -p ./out_logs
err_path=$(realpath ./err_logs)
out_path=$(realpath ./out_logs)
err_log_path="${err_path}/err_$(date +"%d_%m").log"
out_log_path="${out_path}/out_$(date +"%d_%m").log"
while true;
do
echo "starting main from bash"
>&2 echo "starting main from bash"
python3 main.py
echo "done running main sleeping"
sleep 10
echo "list of remaining python processes: "
ps -ax | grep python
echo "closing all of the remaining processes."
ps ax | grep "python" | grep -v grep | awk '{print $1}' | xargs kill;
echo "done closing subprocesses"
# echo "-------test---------" > $out_log_path 2> $err_log_path
done > $out_log_path 2> $err_log_path
Or, if the code has to run over several different days, this:
#!/bin/bash
while true;
do
mkdir -p ./err_logs
mkdir -p ./out_logs
err_path=$(realpath ./err_logs)
out_path=$(realpath ./out_logs)
err_log_path="${err_path}/err_$(date +"%d_%m").log"
out_log_path="${out_path}/out_$(date +"%d_%m").log"
echo "starting main from bash" >> $out_log_path 2>> $err_log_path
>&2 echo "starting main from bash"
python3 main.py >> $out_log_path 2>> $err_log_path
echo "done running main sleeping" >> $out_log_path 2>> $err_log_path
sleep 10
echo "list of remaining python processes: " >> $out_log_path 2>> $err_log_path
ps -ax | grep python >> $out_log_path 2>> $err_log_path
echo "closing all of the remaining processes." >> $out_log_path 2>> $err_log_path
ps ax | grep "python" | grep -v grep | awk '{print $1}' | xargs kill >> $out_log_path 2>> $err_log_path
echo "done closing subprocesses" >> $out_log_path 2>> $err_log_path
echo "-------test---------" > $out_log_path 2>> $err_log_path
done
But this second option is not recommended.
Related Topics
How to Increase the Maximum Number of Characters That Ksh Variable Accepts
What Is the Valid Address Space for a User Process? (Os X and Linux)
How to Schedule a Cron Job to Run 4Th Week of the Year
How to Do Like "Netstat -P", But Faster
Perl - Replace Every Nth (And Multiples) Occurrences of a Character with Another Character
Shell Script to Write and Read Data from Serial Communication
When Running Ls -L, Why Does the Filesize on a Directory Not Match the Output of Du
Why Ln -Sf Does Not Overwrite Existing Link to Directory
How to Not Emit Local Symbols in Nasm So That Gdb Disas Won't Stop at Them
Linux Equivalent of Windows Dll Forwarders or MACos Reexport_Library
Glassfish There Is a Process Already Using the Admin Port 4848
Cmake Test for Processor Feature
Output File Not Created When Reading Sequences
Segmentation-Fault Error Happening with Assembly Code Program
Use Grep to Find the Words That Have Two 'S' Separated by a Space