I have a bash script like this where I pass in a file path into it
groups=$1
file=$2
if $groups
then
sh with_groups.sh $file
else
sh without_groups.sh $file
fi
What I currently do: Open the folder where my file is, do pwd, copy the link, add some_csv.csv to it and run the above script. I want to find a more efficient way to do it.
The equivalent of what I would would be something like
sh ./../run_script.sh true pwd/some_csv.csv
where pwd is the current path I am in (true refers to the first argument. You can disregard that for the purpose of this question)
Related
scripts/a.sh calls scripts/b.sh through source or through sh.
But I cannot be sure that the working directory will be scripts or the parent of scripts or something else.
What is the best practice for referencing b.sh? I can find the directory of the current script, then cd to that directory, and then simply call ./b.sh. But that seems like a lot of code to put into every script that calls another.
There is no need for a cd, cause source or command take a full path. Just get the dir name of the full path of your script and run the script from there.
From bash manual:
0
($0) Expands to the name of the shell or shell script. ....
From man readlink:
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; ...
From man dirname:
dirname - strip non-directory suffix from file name
Altogether:
. "$(dirname "$(readlink -f "$0")")"/b.sh
I've seen some bash scripts that start with something similar to:
DIR=$(dirname "$(readlink -f "$0")")
cd "$DIR"
So the current working directory in a script stays the same, even if user runs it from another directory.
#edit
Like #GordonDavisson suggested in comments, we can also add your dir to PATH:
export PATH="$(dirname "$(readlink -f "$0")")":"$PATH"
Then running:
. a.sh
will search for a.sh script through inside directories listed in PATH variable, which it will find in the first dir.
This could be a dumb question, but how do I make it so a script can be called with "sh [Script Name] [File Path]" and have the script automatically read the file path?
For instance, if I use cp ~/usr/local/bin/testScript ~/Desktop it knows that the target file is the testScript file because it read the path from the command line.
I have a script based on ImageMagick that prompts the user for the file path using "read", processes it, and then drops it onto the desktop. I want the script to skip the actual prompt for the file path, and instead just target whatever file path is entered after calling the script (I.E. sh ConvertPDF /Users/ProfileName/Desktop/testFile.tiff
Positional parameters to the script are available via $n where n >= 1. For n > 9 braces are required in order to distinguish from n < 10.
#!/bin/sh
echo "$2" "$3" "$1"
...
$ ./somescript foo bar 42
I have the following situation:
I have a script with a path of: /usr/local/bin/rsnapshot.period
I want to have symlinks to it in various /etc/cron.[period]/ directories, like /etc/cron.hourly/rsnapshot
I'd like to have the script look up the full path to the symlink, and pull out the [period] part, so I can feed it to rsnapshot.
I can do all the text hacking. The problem I'm having trouble with is getting the path to the calling symlink from within the bash script. $0 seems to point to /usr/local/bin/rsnapshot.period
Is there a better way to get this info?
$0 seems to point to /usr/local/bin/rsnapshot.period
$0 is set by the calling program in its exec*() call, as the first word of the arg argument or the first element of the argv argument. If you feel that the tool you're using is setting this value incorrectly then you should open a bug with the developer.
In the meantime, using a hardlink instead of a symlink will allow you to detect the script name properly, but will break if you aren't careful with the tool you use to edit the main script.
Turns out my problem wasn't that $0 was incorrect - it was pointing to the right place. However, as I was trying to get the absolute path of it, I was using 'realpath' before it, which resolved symlinks.
Passing realpath the '-s' fixed it. Here's my test script and the output of it:
Script:
#!/bin/sh
echo \$0: $0
echo realpath -s \$0: $(realpath -s $0)
echo readlink -e: $(readlink -e $0)
Executed:
$0: ./rsnapshot
realpath -s $0: /etc/cron.hourly/rsnapshot
readlink -e: /usr/local/bin/rsnapshot.period
I am having trouble finding out how to set a directory as an argument in bash.
The directory I am trying to have as an argument is /home/rrodriguez/Documents/one.
Anywhere I try to look for an answer I see examples like dir = $1 but I cant seem to find an explanation of what this means or how to set it up so that it references my specific file location. Could anyone show me how to set up my variable for my path directory?
Adding my code for a better understanding of what im trying to do:
#!bin/bash
$1 == 'home/rrodriguez/Documents/one/'
dir = $1
touch -c $dir/*
ls -la $dir
wc$dir/*
Consider:
#!bin/bash
dir=$1
touch -c "$dir"/*
ls -la "$dir"
This script takes one argument, a directory name, and touches files in that directory and then displays a directory listing. You can run it via:
bash script.sh 'home/rrodriguez/Documents/one/'
Since home/rrodriguez/Documents/one/ is the first argument to the script, it is assigned to $1 in the script.
Notes
In shell, never put spaces on either side of the = in an assignment.
I omitted the line wc$dir/* because it wasn't clear to me what the purpose of it was.
I put double-quotes around $dir to prevent the shell from, among other things, performing word-splitting. This would matter if dir contains spaces.
So I am trying to make a portable bashrc/bash_profile file. I have a single script that I am symbolically linking to .bashrc, .bash_profile, etc. I am then looking at $0 and switching what I do based on which script was called. The problem is what the shell calls the bashrc script of course it executes bash really which means $0 for me is -bash. $1 further more is not set to the script name.
So my question is, in bash how can I get the name of the script being executed. Not the binary executing it, e.g. bash?
I assume its giving me -bash with $1 not being set because it is really not a new process. Any ideas?
Try:
readlink -f ${BASH_SOURCE[0]}
or just:
${BASH_SOURCE[0]}.
Remarks:
$0 only works when user executes "./script.sh"
$BASH_ARGV only works when user executes ". script.sh" or "source script.sh"
${BASH_SOURCE[0]} works on both cases.
readlink -f is useful when symbolic link is used.
The variable BASH_ARGV should work, it appears the script is being sourced
$BASH_ARGV
create .sh file lets say view.sh then put
#!/bin/bash
echo "The script is being executed..."
readlink -f ${BASH_SOURCE[0]}