So how can I instruct tar to ignore missing input files?
It's really simple: just use the --ignore-failed-read
flag on your tar
command:
$/bin/tar -cz --ignore-failed-read data config myfile 2>/dev/null | /bin/dd of=backup.tar 2>/dev/null
$ echo ${PIPESTATUS[0]}
> 0
BTW: Note that the answer of Hauke Laging is more cumbersome, but tar
only returns 0 if it's all ok, or if the only file missing is myfile
... with this, tar
returns 0 if it's all ok, or even when any file is missing.
With this:
/bin/tar -cz --ignore-failed-read data config myfile | /bin/dd of=backup.tar 2>/dev/null
(note that I'm not redirecting stderr
of tar
to /dev/null
) if myfile
doesn't exist, tar
returns 0
(if there is no other errors, of course) and you get this on stderr
: /bin/tar: myfile: Warning: Cannot stat: No such file or directory
tar
manual says:
‘--ignore-failed-read’
Do not exit with nonzero on unreadable files or directories.
This option has effect only during creation. It instructs tar to treat
as mild conditions any missing or unreadable files (directories). Such failures
don’t affect the program exit code, and the corresponding diagnostic
messages are marked as warnings, not errors. These warnings can be suppressed
using the ‘--warning=failed-read’ option
but, alas, --warning=failed-read
suppress all warnings about read-errors: in your case, suppress warnings about a file that doesn't exist, but also suppress warning about I/O errors, for example... is far from optimal; apparently, tar
doesn't have a flag to say it: hey, suppress failed-read warning only if the file doesn't exist, so, may be, this resolve your problem:
/bin/tar -cz --ignore-failed-read data config myfile 2> >(grep -v 'No such file or directory' 1>&2) | /bin/dd of=backup.tar 2>/dev/null
this: >( ... )
is Process Substitution
this way, your tail
command doesn't change its return number if the file doesn't exist, you don't get warning messages about missing files, and you get warning messages about any other read error.
this>
I can't help thinking that none of this solutions are really good, so, I came up with this:
/bin/tar -cz -T <(\ls -A -1) 2>/dev/null | /bin/dd of=backup.tar 2>/dev/null
with this, your are sending to tar
only the files that really exists at the time of command execution: you don't need to worry about their names, or even which file exists or not: you always execute the same command (no matter what), scales perfectly if you have 1 file missing, or n files missing, and you don't miss any errors.
(note the backslash if front of ls
command: this way, you prevent any ls
alias, thus, its output is more reliable)