bash script that works both on Ubuntu and MacOsX - linux

I've created an install.sh files for my ubuntu machine. This file aims to start configuration of my dotfiles in an ubuntu machine. But I've also a MacOsX machine.
#!/bin/bash
clear
SCRIPT=$(readlink -f $0)
SCRIPTPATH=`dirname $SCRIPT`
cd $SCRIPTPATH && git submodule update -i
rm -rf ~/.vim
ln -s $SCRIPTPATH/.vim ~/.vim
rm ~/.vimrc
ln -s $SCRIPTPATH/.vimrc ~/.vimrc
rm ~/.bashrc
ln -s $SCRIPTPATH/.bashrc ~/.bashrc
This is what I get if I run same script in MacOsX:
readlink: illegal option -- f
usage: readlink [-n] [file ...]
usage: dirname path
fatal: Not a git repository (or any of the parent directories): .git
How can I convert my "install.sh", thus it can run both on MacOsX and Ubuntu?

Just use the first argument for the scriptname:
SCRIPT="$0"
$0 is always available and always contains the full script name. You only need readlink if you are executing the script from a link in order to return the actual target name of the script.

Related

Not unzipping all files while using 7z in shell script

I am using below command
echo "A"|7z x -r -y /usr/sap/Silentinstall/commerce/commerce.7z.001
When I ran it from linux machine i.e. from cmd it works and it unzips all the files and folders.
But It it not extracting full files and folder when I am running it in shell script as below
#!/bin/sh
cd /usr/sap/Silentinstall/commerce
echo "A"|7z x -r -y /usr/sap/Silentinstall/commerce/commerce.7z.001
chmod -R 777 /usr/sap/Silentinstall/*
After lot of approaches i found below Solution,
cd /usr/sap/Silentinstall/commercedownloads
7z x /usr/sap/Silentinstall/commercedownloads/testcomm.7z.001 -o/usr/sap/Silentinstall/commercedownloads -aoa -r >>/usr/sap/Silentinstall/commercedownloads/log.txt
chmod -R 777 /usr/sap/*

How to make shell script executable after decompress without chmod

I am studying linux, and I have to make all shell scripts executable by this command:
find ./ -name "*.sh" -exec chmod u+x {} \;
But when I download Logstash.tar.gz and extract it to /opt, all shell scripts were executable, no chmod needed. And /opt is not in $PATH.
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin
How do I build an app like logstash works?
===updated test steps for verification===
mkdir testtar && cd testtar
## create a executable script
echo test_with_x >> test_with_x.sh
chmod u+x test_with_x.sh
## create a not executable script
echo test_without_x >> test_without_x.sh
cd ..
## compress with gzip
tar -zcvf testtar.tar.gz ./testtar
mkdir testextract
mv testtar.tar.gz ./testextract
cd ./testextract
tar -zxvf testtar.tar.gz
## decompressed and see a executable and not executable script
Logstash tar bundle might have been created with executable permissions on all scripts. It should be the reason why it works fine after extracting without using chmod u+x command. If you also create a tar bundle with executable scripts, you should also get executable scripts after decompressing without using chmod u+x.
If you want your shell scripts to be executed without using chmod u+x, provide your shell script as an argument to your shell interpreter.
For e.g,
bash MyScript.sh
sh MyScript.sh
ksh MyScript.sh
You have two solution:
Add /opt to the PATH:
export PATH=${PATH}:/opt
call logstash with full path:
/opt/<anywhere.it.may.be>/logstash

Is there a quick method on linux to switch to recently accessed n folders (n > 1)?

We can use cd - to access the most recently accessed folder, but what if I want to quickly switch to the last but one folder accessed?
Sure there's a way!
You want the shell builtin pushd.
[~]$ pwd
/home/dan
[~]$ pushd /tmp
/tmp ~
[tmp]$ pushd /usr/bin
/usr/bin /tmp ~
[bin]$ pushd +2
~ /usr/bin /tmp
[~]$
ls -t | head -n1
Above command use to get most recently used directory

Copying files with wildcard (*) to a folder in a bash script - why isn't it working?

I am writing a bash script that creates a folder, and copies files to that folder. It works from the command line, but not from my script. What is wrong here?
#! /bin/sh
DIR_NAME=files
ROOT=..
FOOD_DIR=food
FRUITS_DIR=fruits
rm -rf $DIR_NAME
mkdir $DIR_NAME
chmod 755 $DIR_NAME
cp $ROOT/$FOOD_DIR/"*" $DIR_NAME/
I get:
cp: cannot stat `../food/fruits/*': No such file or directory
You got that exactly backwards -- everything except the * character should be double-quoted:
#!/bin/sh
dir_name=files
root=..
food_dir=food
fruits_dir=fruits
rm -rf "$dir_name"
mkdir "$dir_name"
chmod 755 "$dir_name"
cp "$root/$food_dir/"* "$dir_name/"
Also, as a matter of best-practice / convention, non-environment variable names should be lower case to avoid name conflicts with environment variables and builtins.

Copy and overwrite a file in shell script

I want to copy a certain file to a location, irrespective of that file already exists in the destination or not. I'm trying to copy through shell script.But the file is not getting copied. I'm using the following command
/bin/cp -rf /source/file /destination
but that doesn't work.
Use
cp -fr /source/file /destination
this should probably solve the problem.
This question has been already discussed, however you can write a little script like this:
#!/bin/bash
if [ ! -d "$2" ]; then
mkdir -p "$2"
fi
cp -R "$1" "$2"
Explaining this script a little bit
#!/bin/bash: tells your computer to use the bash interpreter.
if [ ! -d "$2" ]; then: If the second variable you supplied does not already exist...
mkdir -p "$2": make that directory, including any parent directories supplied in the path.
Running mkdir -p one/two/three will make:
$ mkdir -p one/two/three
$ tree one
one/
└── two
└── three
If you don't supply the -p tag then you'll get an error if directories one and two don't exist:
$ mkdir one/two/three
mkdir: cannot create directory ‘one/two/three’: No such file or directory
fi: Closes the if statement.
cp -R "$1" "$2": copies files from the first variable you supplied to the directory of the second variable you supplied.
So if you ran script.sh mars pluto, mars would be the first variable ($1) and pluto would be the second variable ($2).
The -R flag means it does this recursively, so the cp command will go through all the files and folders from your first variable, and copy them to the directory of your second variable.
Your problem might be caused by an alias for cp command created in your system by default (you can see al your aliases by typing "alias").
For example, my system has the following alis by default: alias cp='cp -i', where -i overrides -f option, i.e. cp will always prompt for overwriting confirmation.
What you need in such case (that'll actually work even if you don't have an alias) is to feed "yes" to that confirmation. To do that simply modify your cp command to look like this:
yes | cp /source/file /destination
/bin/cp -rf src dst
or
/usr/bin/env cp -rf

Resources