I am working on a simple shell script (my first one) and cannot seem to figure out why this is failing when I run ./auto.sh baz. It was working initially when I had hard coded in the full destination path, but now that I want to use an argument it breaks. Any help would be awesome. Thanks!
#!/bin/sh
cp -ivr ./foo/bar.xcodeproj ./iOS/$1.xcodeproj
Try the following
#!/bin/sh
cp -ivr "./foo/bar.xcodeproj" "./iOS/${1}.xcodeproj"
Related
On MSYS2 on my Windows machine, I have to switch to bash because tcsh is flaky and after an hour of messing around with completion scripts, .bashrc and .inputrc, I have almost got bash to behave in a way I am used to. However, there's one piece missing.
In tcsh, I could list the current directory on a single TAB press (i.e., a blank command). I am sure there's a way to do this in bash with the complete -E option, but I can find no examples.
Any help is appreciated!
Regards
This will do what you want:
complete -Ef
Now try <tab><tab>
I was able to get what I wanted with this:
_listall ()
{
COMPREPLY+=( $( ls ./))
}
complete -F _listall -E
So I am a rookie in Linux and I need some help. I have to write a bash script in which I have to use the parent directory of the script to create a file there, wherever the script would be. It should look like this:
If my script it's in "/home/student/", I need to create, using an in-script command another file called txt in /home/. Any ideas please? Thank you.
There's a subtlety if you want to be able to run your script from anywhere.
eg: if your script is in /home/myHome/someDir/someOther, and you want to create a file in /home/myHome/someDir wherever you are when you run your script.
To solve it, you just need to first derive the directory where your script is.
It can be done using:
SCRIPT_DIRECTORY="$(dirname "$0")"
touch "$SCRIPT_DIRECTORY/../myFile.txt"
Edit: Actually it can be even more subtle, if you want to handle symlinks. ie: if the symlink /home/myHome/mySymlink points at your script, and is the one actually being called, then the previous script will consider /home/myHome/ instead of /home/myHome/someDir/someOther
To handle this case you can do
if [ -L "$0" ] && [ -x $(which readlink) ]; then
ACTUAL_SCRIPT_FILE="$(readlink -mn "$0")"
else
ACTUAL_SCRIPT_FILE="$0"
fi
SCRIPT_DIRECTORY="$(dirname "$ACTUAL_SCRIPT_FILE")"
touch "$SCRIPT_DIRECTORY/../myFile.txt"
use .. to point to parent directory. So you could create a file using something like
MY_SCRIPTDIR="$(dirname $0)"
touch ${MY_SCRIPTDIR}/../abc.txt
From your command prompt or within shell script.
Unfortunately, the other answers either give you the current working directory instead of the directory the script is in, or they will not work if either the script or one of the directories along the way is a symbolic link rather than a real directory.
What will work is:
dirname $(readlink -f "$0")
Explanation:
"$0" is the name of the script as you type it in your command line. Quoting is important for the case it contains whitespace.
readlink will resolve any symbolic links along the way
dirname takes just the directory name from script's full path - it's better readable and safer for corner cases than manually looking for slashes etc.
Now, you will get the correct result even in a complex case: if your script is in /tmp and you create a symbolic link to it in /tmp/abc/, and your current directory will be /home and you run /tmp/abc/your-script, it will correctly output /tmp, not /home nor /tmp/abc.
I just bumped into a bug in redis install_server script
it has a hardcoded :
DEFAULT_CONFIG="../redis.conf"
so when running this script not from its own folder (such as ./utils/install_server.sh)
the script fails to find the conf file.
I'm looking for a way to reference the scripts folder without a dependency on where the script is called from.
I looked into this answer which seems to be the canonical on SO but something is failing for me:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo $DIR
and I get:
./utils/install_server.sh: 100: ./utils/install_server.sh: Bad substitution
/home/myusername/binaries/redis-2.8.3 #where I run the script from..not the folder I need
So I guess I'm doing something wrong, or this isn't the correct answer for me
I know I can add a check if the file exists and a clearer error message to the redis install script, but I rather just make this work.
I'll be glad for ideas, and I'll make a PR to redis to fix this for everyone..
Thanks!
I do something very similar to what you have posted:
SCRIPT_DIR="$(cd $(dirname $0) && pwd)"
It seems that in your case, something is wrong with BASH_SOURCE. In my approach, I use $0 which always evaluates to the full pathname used to launch the script.
I'm not sure what the problem with BASH_SOURCE is in your script as what you posted works for me. Thus I am just offering an alternate approach.
Are you running this with bash (i.e. start the script with #!/bin/bash or run it with bash /path/to/script), or plain sh (#!/bin/sh or sh /path/to/script)? Both BASH_SOURCE and arrays ([0]) are bash extensions, and may not be available in a generic shell. In particular, the "Bad substitution" error is one I've seen from trying to use arrays in a shell that doesn't support them.
Here's my situation:
I have multiple versions of a script in source code control where the name differs by a path name component (ex: scc/project/1.0/script and scc/project/1.1/script). In another directory, there is a symlink to one of these scripts. The symlink name is not related to the script name, and in some cases may change periodically. That symlink, in turn, is sourced by bash using the '.' command.
What I need to know: how do I determine the directory of the referenced script, on a 10 year-old system with Bash 2 and Perl 5.5? For various reasons, the system must be used, and it cannot be upgraded.
In Bash 3 or above, I use this:
dir=`perl -MCwd=realpath -MFile::Basename 'print dirname(realpath($ARGV[0]))' ${BASH_SOURCE[0]} $0`
Apologies for the Perl one-liner - this was originally a pure-Perl project with a very small amount of shell script glue.
I've been able to work around the fact that the ancient Perl I am using doesn't export "realpath" from Cwd, but unfortunately, Bash 2.03.01 doesn't provide BASH_SOURCE, or anything like it that I've been able to find. As a workaround, I'm providing the path information in a text file that I change manually when I switch branches, but I'd really like to make this figure out which branch I'm using on its own.
Update:
I apologize - apparently, the question as asked is not clear. I don't know in every case what the name of the symlink will be - that's what I'm trying to find out at run time. The script is occasionally executed via the symlink directly, but most often the link is the argument to a "." command running in another script.
Also, $0 is not set appropriately when the script is sourced via ".", which is the entire problem I'm trying to solve. I apologize for bluntness, but no solution that depends entirely upon $0 being set is correct. In the Perl one-liner, I use both BASH_SOURCE and $0 (BASH_SOURCE is only set when the script is sourced via ".", so the one-liner only uses $0 when it's not sourced).
Try using $0 instead of ${BASH_SOURCE[0]}. (No promises; I don't have a bash 2 around.)
$0 has the name of the program/script you are executing.
Is stat ok? something like
stat -c %N $file
bash's cd and pwd builtins have a -P option to resolve symlinks, so:
dir=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
works with bash 2.03
I managed to get information about the porcess sourcing my script using this command:
ps -ef | grep $$
This is not perfect but tells your which is the to process invoking your script. It migth be possible with some formating to determine the exact source.
I want to create a simple bash script to launch a Java program on OS X. The names of the file, the file path, and the immediate working folder all contain spaces. When I do this:
#!/bin/sh
cd `dirname $0`
I get
usage: dirname path
I have also tried putting quotes in all kinds of different places. The most elaborate example being
cd "`dirname \"$0\"`"
Nothing has worked. I either get error messages or that cryptic "usage: dirname path" message.
What are other methods that might work?
Edit: this doesn't seem to be an issue for anyone but me so it must just be my box. I'm going to accept my own post below because it's the only solution which worked for this specific problem. However I'm definitely upvoting the solutions which seem to be working for everyone else and really appreciate everyone's help.
What about:
cd "$(dirname "$0")"
That works for me here.
#!/bin/sh
cd "$(dirname "$0")"
What finally worked for me is changing this:
#!/bin/sh
cd `dirname $0`
To this:
#! /bin/zsh
cd "${0:h}"
This also supports file names and file paths containing spaces. Here's where I found it: http://rentzsch.com/unix/locationAwareCommandFiles
Escaping the inner double quotes is unnecessary:
cd "`dirname "$0"`"
But that doesn't get to the root of the problem, which is that somehow the value of $0 appears to be empty, or perhaps something strange. Try changing running your script this way:
bash -x scriptname
This will echo each line, with variables interpolated, before running it. It is very useful for debugging. Also quite helpful are:
-u: abort on attempt to use undefined variable
-e: abort on first error
Hey not sure about this... But is it possible that your
#!/bin/sh
Points to something that is not bash? What I usually use is:
#!/usr/bin/bash
Pretty new to the whole scripting thing so not sure.