Shell Script - opening files from a different directory - shell

I am trying to cd to a different directory by using a path to open a file, but it fails to load correctly.
I am in the directory of ~/Dev/.../Examples to run a ./test.sh script.
Inside the shell script, I have the following:
#!/bin/bash
path = '~/Datasets/foo'
....
"path"/bar
The Dataset folder is right after cd ~/
I have tried $HOME instead of ~, but it still fails to load the respective file.

Here is a code to open the bar directory with nautilus (ubuntu's explorer):
#!/bin/bash
path='/home/your_user_name/foo'
nautilus $path/bar/
Rules:
Use absolute path: /home/your_user_name/, not ~/ nor $HOME.
Bash doesn't like spaces: path='~/Datasets/foo', and not path = '~/Datasets/foo'

Related

executing a python code located in a subfolder

I have a directory called NHOME. In this directory there is a folder named subFolder. It's like this:
/NHOME/subFolder
In NHOME directory I'm executing a bash script which intends to execute a python code located in subFolder. I have problem doing this. I tried something like this:
./subFolder/file.py
but it didn't work. Is this possible?
Use pwd to get the script's location instead of the relative ./
pythonScript="$PWD/subFolder/file.py"
To run:
#!/bin/bash
"$PWD"/subFolder/file.py
Note: The " around $PWD are needed if the path contains spaces ()

Change directory in bash script in windows

How can I change my working directory in bash script in windows. I have
~dp0 = C:\test\docker\windows and I want to change my directory to C:\test\build
So it means 2 levels up and then int o build folder
Thanks
Since C:\ is mounted by default into /mnt/c this will work.
Create a .bashrc in your home path by following command:
echo "BUILDDIR=/mnt/c/test/build" >> ~/.bashrc;source ~/.bashrc
cd $BUILDDIR
# Do your work below for example ./configure.
./configure
On my system in Git bash the C:\ root is just /c/ and other dirs from there are whatever they are, so it would be cd /c/test/build/.
You could also still say cd ../../build/.
Good luck.
To change the directory using a bash script is just like you would using normal bash.
cd "C:/test/build"
echo "You're now in the folder, do what you will."
Save the file as .sh and it can be used as such.
Note, when navigation your folders using a bash script remember the directory you'll be starting from is always the home directory.

Double Clicking a shell script on Mac

i have a small script that runs a jar file :
#!/bin/bash
prefix="foo";
name=`ls ${prefix}*.jar`;
echo $name;
java -jar $name prop1.properties prop2.properties
when i run it in the terminal using ./myscript.sh, it works fine and the jar file executes, but when i rename it in myscript.command and double click it, i have this error :
ls: foo*.jar : No such file or directory
I saw that apparently a .command file opens a terminal at the root directory, so I tried finding the directory containing myscript.command using that :
dir = 'find <dir> -maxdepth 1 -type d -name '*myDirContainingJar*' -print -quit'
cd $dir
but dir is just blank, any ideas ???
Opening a shell script from Finder on macOS (whether it has extension .command or is an extension-less executable shell script) makes the current user's home directory the current directory (as of macOS 10.12).
To explicitly change to the directory in which the script itself is located in a bash script, use:
cd -- "$(dirname -- "$BASH_SOURCE")"
In this invocation scenario, the following POSIX-compliant variation, which uses $0 in lieu of $BASH_SOURCE, would work too: cd -- "$(dirname -- "$0")"
Note:
Generally, if your script is invoked via a symlink and you want to change to the target's directory (the actual script file's directory as opposed to the directory in which the symlink is located), more work is needed - see this answer of mine.
When opening a script from Finder, however, this issue does not apply, because Finder itself resolves a symlink to its (ultimate) target and then invokes the target directly.
The problem with your script is that it runs with a different working directory than you tested it with. When you do ls something in a script, the script looks in the current working directory (where you cded last in case you're in a terminal), not in the directory the script is in. In general, when writing scripts like this you should use the full path of the file you're referring to or figure out the directory of the script and point to the file relative to that. One solution works in Bash, but it might not in the shell you're using.

Always get the full path of a relative file in bash

I have a bash script located in /home/http/mywebsite/bin/download.sh
I have a config file in /home/http/mywebsite/config/config.yaml
Now I want to read the yaml file no matter where I execute my script.
The problem:
When I cd into /home/http/mywebsite/bin/ and run ./download.sh everything works.
When I cd into /home/ and run http/mywebsite/bin/download.sh it can not find the config file because of the relative path.
How do I make sure I can always read the config file no matter where I execute the script. It is always located 4 directories up from the script in config/config.yaml
The script looks like this:
#!/bin/bash
# This will give me the root directory of my project which is /home/http/mywebsite/
fullpath="$( cd ../"$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cat ${fullpath}config/config.yaml
This works if I execute it inside the directory where the script is.
If I execute the script from another directory such as /home/ I get the following error:
cd: ../http/mywebsite/bin: No such file or directory
cat: config/config.yaml: No such file or directory
Solution?
If it is possible it would be great with a code snippet that can traverse up a path N amount of times, this would solve my problem. But it is too advanced for me.
For example you can set a variable "cd_up=1" how many times to go up. The run the loop/sed or whatever magic.
And it would turn the absolute string from:
/home/http/mywebsite/bin/
into:
/home/http/mywebsite/
And changing it to 2 it would change the string to:
/home/http/
Managed to solve it finally by using:
#!/bin/bash
cd "$(dirname "$0")"
BASE_DIR=$PWD
# Root directory to the project
ROOT_DIR=${BASE_DIR}/../
cat ${ROOT_DIR}config/config.yaml
This allows me to execute the script no matter where I am.
You can use which command to determine absolute path of the executing script no matter where you are running
BASE_DIR=$(which $0 | xargs dirname)
ROOT_DIR=${BASE_DIR}/../..
cat ${ROOT_DIR}/config/config.yaml
Lets try printing the path from different locations.
-bash-4.1$ /tmp/dir.sh
$0 - /tmp/dir.sh. Absolute path - /tmp
-bash-4.1$ cd /tmp
-bash-4.1$ ./dir.sh
$0 - ./dir.sh. Absolute path - /tmp
-bash-4.1$
-bash-4.1$ cd /usr/bin
-bash-4.1$ ../../tmp/dir.sh
$0 - ../../tmp/dir.sh. Absolute path - /tmp

Script location execution

I've been working on a script but always with a fixed directory (/opt/mw/script).
I need to change that to be able to execute the script from any directory.
I think I will need to add a "." at the beginning of the line to be able to execute the script?
For example ./mw/script
Is this correct?
Thanks
You already can execute that script from any directory with that absolute file path. It's the relative file paths (that start with ./ or ../) that can only be executed from a specific directory.
You need to add the "." if the script is in the current directory (e.g. ./script), but it is optional if the script is already inside another directory (e.g. mw/script).
Also notice that if your script contains relative references to other files and directories, you may need to use this trick to properly refer to them from any directory.
For instance, consider the following script using absolute paths:
#!/bin/bash
# lists all files in this directory
ls /opt/mw
If it is converted to relative paths as follows:
#!/bin/bash
# lists all files in this directory
ls mw
Then this script will only work if you run it from its own directory (e.g. cd /opt/ && ./script).
But then you can generalize it like this:
#!/bin/bash
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# lists all files in this directory
ls $SCRIPT_DIR/mw
Now the script works even when executed from another directory.

Resources