Including a chunk of code in a shell script - bash

I have a number of shell scripts that all look like this:
#!/bin/bash
cd ~/Dropbox/cms_sites/examplesite/media
sass -C --style compressed --update css:css
cd ~/Dropbox/cms_sites/examplesite
rm -f ./cache/*.html
rm -fr ./media/.sass-cache/
rm -fr ./admin/media/.sass-cache/
rsync -auvzhL . username#host:/home/username/remote_folder
(I know the use of cd seems weird, but they have evolved!)
Now, all these scripts have a few differences, in that they have different usernames, hosts, local folder and remote folder names, and I want an inexperienced user to be able to run them without arguments (so he can drag and drop them into a terminal without issue).
What I'd like to do is something like:
#!/bin/bash
cd ~/Dropbox/cms_sites/examplesite/media
sass -C --style compressed --update css:css
cd ~/Dropbox/cms_sites/examplesite
include ~/scripts/common.sh
rsync -auvzhL . username#host:/home/username/remote_folder
then have a file in common.sh that looks like:
rm -f ./cache/*.html
rm -fr ./media/.sass-cache/
rm -fr ./admin/media/.sass-cache/
so that I can easily change sections of the code in lots of scripts at once.
Is this possible, or is there a better way to do this without using arguments and having one script?

Use the source command. It's bash's version of 'include'

No need for "include" if the script is executable:
~/scripts/common.sh
If the script is not executable or does not have an appropriate shebang line then you'll need to specify the interpreter:
bash ~/scripts/common.sh

Related

Cygwin BASH script file - unwanted single quotes added automatically to constant string - how to prevent

I have this BASH script which I run in a Cygwin terminal instance via the command
bash -f myfile.sh
All I need it to do is delete all *.txt files in the Cygwin /home/user directory.
#!/bin/bash
set -x
rm -rf /home/user/*.txt
This does not work, running the file (I only added "set -x" to debug when it started failing) shows
+ rm -rf '/home/user/.txt*
The problem is literally that I specify in my code in the Cygwin BASH script
rm -rf /home/user/*.txt
without any quotes, but when ran in Cygwin terminal in the BASH script, it resolves to
rm -rf '/home/user/*.txt'
e.g. single quotes are added by Cygwin BASH.
I've scoured other posts where the responses indicate the quotes are only there due to "set -x" formatting the output to show a unitary string, but without "set -x" in the script file the rm command still fails, e. g. the rm command string IS still quoted (or some other mangling is applied?), and therefore the rm line in the script does not work.
I managed to confirm that by manually running in the Cygwin terminal
rm -rf '/home/user/*.txt'
which does nothing (it just returns, leaving the .txt files intact in /home/user/), and then running
rm -rf /home/user/*.txt
manually, which does work perfectly, deleting all .txt files in the /home/user/ directory under the Cygwin terminal.
How can I get the above command to remove all .txt iles in /home/user/ from inside a Cygwin terminal BASH script file?
Thanks!
As intimated above, the answer to this is to not use -f when calling bash, e. g.
just
bash myfile.sh

bash shell generates a link that was not specified

I wrote a simple bash script (in /homedir) to run an executable and then move the outputs to /workdir. I also made a soft link of /workdir named work to /homedir for me to switch easily between folders.
All steps are working well, except that an unspecified soft link named 'grids' is created in /workdir to itself. I can't delete it otherwise all outputs are gone as well.
How can this happen?
#!/bin/bash
cd ..
expname=`basename "$PWD"`
echo 'experiment name: '$expname
homedir=/home/b/b380963/icon_foehn/$expname/grids/
workdir=/work/bb1096/b380963/icon_foehn/$expname/grids/
if [ ! -d ${workdir} ]; then
mkdir -p ${workdir}
fi
cd $homedir
ln -s ${workdir} work
cd /home/b/b380963/nwp/dwd_icon_tools_v2/icontools/
./icongridgen --nml $homedir/gridgen_MCH_july.nml
mv ICON_1E_* $workdir/
mv base_grid* $workdir/
It's quite easy to see in your code:
workdir=/work/bb1096/b380963/icon_foehn/$expname/grids/
...
ln -s ${workdir} work
The command ln -s is the command, creating the symlink.
If you don't like the creation of that symlink, you might put that line in comment (don't delete it: in case you're not satisfied, it's easier to uncomment it).
You can solve your issue, using this command:
ln -sTf ...
This removes the existing destination files beforehand.

How to pass a directory path containing spaces to the -C option of tar in a bash script?

i'm building up in a bash script a tar command like this:
/usr/bin/tar -cvjf /tmp/archive.tar.bz2 -X excl.txt -C '/cygdrive/c/Users/Utente/dir with spaces/' dir1 dir2 dir2
/usr/bin/tar: '/cygdrive/c/Users/Utente/dir: Cannot open: No such file or directory
if i test the command in the shell it works fine.
if i run the script the script complains. i think that something fails when tar tries to change directory.
of course i can change directory in the script an then avoid the use of the -C option but i miss the opportunity to use the -X option.

Difference between alias rm and /bin/rm

What is the difference between using /bin/rm abc.txt and the times when sometimes you have to alias rm which is then performed with rm abc.txt
/bin/rm will always refer to the binary rm command on your system. If you just write rm abc.txt one of these may happen:
Your shell implements rm directly as a builtin function or there is a shell function called rm (no external command is run).
rm has previously been aliased (with alias rm=<substituted-command>) to mean something different. Usually the aliased command is similar in function but it does not have to be.
If none of the above is applicable, the shell looks up the external command in /bin and runs it.
You can use alias to see all defined aliases. Also check out the command -V shell builtin which can tell you if a given command is an external command, shell function, builtin or special builtin.
A typical reason to create an alias for rm is to add the -i or -I option. In "interactive" mode rm will ask for confirmation before deleting anything.
$ alias rm="/bin/rm -i"
$ rm myfile
rm: remove regular file ‘myfile’? _

Extract all tar.bz2 files to a directory

I have many tar.bz2 files in a directory, and would like to extract them to another directory.
Here is my bash script:
for i in *.tar.bz2 do;
sudo tar -xvjf $i.tar.bz2 -C ~/myfiles/
done
It doesn't work. How can I make it work? Thanks!
Your variable $i contains the entire file name (as you have applied the regex *.tar.bz2). So inside your for loop you don't need to attach the extension.
Try:
for i in *.tar.bz2; do
sudo tar -xvjf "$i" -C ~/myfiles/
done
You also have ; misplaced.

Resources