0

I got a tar command line that works great straight in the shell.

tar --exclude=out/pictures/\*.{jpg,gif,png,jpeg} --exclude=tmp/\*.{txt,php} --exclude=log/\*.{log,sql} -cvf /backups/mydomain.tar -C /var/www/vhosts/mydomain.com/httpdocs content

As soon as I put this command in a bash script and execute, it ignores the excludes parameters.

I tried some various syntax like:

tar --exclude="out/pictures/\*.{jpg,gif,png,jpeg}" -cvf /backups/mydomain.tar -C /var/www/vhosts/mydomain.com/httpdocs content

tar --exclude='out/pictures/\*.{jpg,gif,png,jpeg}' -cvf /backups/mydomain.tar -C /var/www/vhosts/mydomain.com/httpdocs content

tar --exclude out/pictures/\*.{jpg,gif,png,jpeg} -cvf /backups/mydomain.tar -C /var/www/vhosts/mydomain.com/httpdocs content

tar --exclude= out/pictures/\*.{jpg,gif,png,jpeg} -cvf /backups/mydomain.tar -C /var/www/vhosts/mydomain.com/httpdocs content

But nothing works. The exclude parameters are simply ignored.

A simple --exclude like --exclude="tmp" works as intended. As soon I start to work with parameters it breaks cause of the syntax I assume.

Im running tar (GNU tar) 1.29 on ubuntu 18.04.5.

schily
  • 18,806
  • 5
  • 38
  • 60
Kuba
  • 1
  • 3
  • Welcome, you should use an absolute path: `/abs/path/out/pictures/` if the script is not in the same directory. – schrodingerscatcuriosity Oct 13 '20 at 15:46
  • This is no absolute path problem. Things like `--exclude=out/pictures` works grea but `--exclude=out/pictures/\*.{jpg,gif,png,jpeg}` dont work. – Kuba Oct 13 '20 at 15:50
  • The original command-line syntax should work as-is. You're escaping the asterisk character so that the shell does not expand it, but you're also letting the shell expand the `{jpg,gif,png,jpeg}` part. Are you sure that the command doesn't work, when copy-pasted as is? – Haxiel Oct 13 '20 at 16:28
  • 1
    What is the shebang? Are you sure the shell interpreting the script expands `{jpg,gif,png,jpeg}`? This syntax is *not* portable. – Kamil Maciorowski Oct 13 '20 at 16:57
  • An off-the-wall work-around: (a) mv -t /somewhere out/pictures (on the same device so it does a cheap move, not an expensive copy). (b) Run tar without the excludes. (c) mv -t httpdocs out/pictures. – Paul_Pedant Oct 13 '20 at 16:58
  • Less off-the-wall: mark those excluded directories as *caches*, using one of the options `--exclude-caches-all` or `--exclude-tag-all`. You might at least get a better class of bug. – Paul_Pedant Oct 13 '20 at 17:09

3 Answers3

0

The brace expansion only works in bash and not sh. Make sure your shebang is set to bash:

#!/usr/bin/env bash

Make your script executable and call it directly

chmod +x myscript.sh
./myscript.sh

You can always verify the expansion by putting an echo in front of your command.

echo tar --exclude=out/pictures/\*.{jpg,gif,png,jpeg} --exclude=tmp/\*.{txt,php} --exclude=log/\*.{log,sql} -cvf /backups/mydomain.tar -C /var/www/vhosts/mydomain.com/httpdocs content
zsolt
  • 11
  • 2
0

Ok, I learned something essential today.

The bash shell supports the brace expansion. The sh shell (is the sh a shell?) however not.

And by running the script with sh myscript.sh like I did, the script was executed with the sh shell. bash myscript.sh works instant.

But shouldn't the link #!/bin/bash in the sh file force the script to execute anyway with bash?

Can someone explain? Im a bit confused.

Running it as ./script.sh will make the kernel read the first line (the shebang), and then invoke bash to interpret the script. Running it as sh script.sh uses whatever shell your system defaults sh to (on Ubuntu this is Dash, which is sh-compatible, but doesn't support some of the extra features of Bash).

This would explain everything but the default shell echo $SHELL on my ubuntu is bash (this quote is from 2010 so I assume back then the default shell was dash on ubuntu).

I would like to understand it, even if it works with bash myscript.sh.

Kuba
  • 1
  • 3
  • If you explicitly run a script with `sh`, it does not examine the SHELL variable. It just finds the first `sh` on the current path. That may be a real Bourne `sh`, but more usually it is a link to (or copy of) the POSIX-conforming shell in that distro -- may be dash or ksh or something else. When you explicitly run a script with a given shell, it just reads the script as text, so the shebang is just a comment. Only the kernel actions the shebang, when it finds the script as an executable. – Paul_Pedant Oct 13 '20 at 23:07
  • Please see [how the site is supposed to work](https://unix.stackexchange.com/tour). My main point: do not ask a follow-up question in an answer. – Kamil Maciorowski Oct 13 '20 at 23:41
  • An explicit interpreter (e.g. `sh myscript.sh` or `bash myscript.sh`) takes precedence over the shebang line (see my answer [here](https://unix.stackexchange.com/questions/580124/does-zsh-respect-the-shebang-bin-sh-so-dash-can-be-used)). `$SHELL` is not relevant -- that's the default interactive shell for your user account, and has no effect on scripts (unless you use `source` or `.` to run the script *in* your interactive shell). – Gordon Davisson Oct 14 '20 at 00:10
  • Thank you for the clarification Paul_Pedant and Gordon Davisson. – Kuba Oct 14 '20 at 07:48
0

Give it a try:

tar --exclude="out/pictures/*.{jpg,gif,png,jpeg}" -cvf /backups/mydomain.tar -C "/var/www/vhosts/mydomain.com/httpdocs content"
Dr. Alexander
  • 371
  • 3
  • 7