So apparently, I can't source a script if that script is in the current directory. For example,
# source some/dir/script.sh
Ok
works fine, but if I'm in the same dir as the script, it errors out:
# cd some/dir
# source script.sh
-sh: source: script.sh: file not found
What gives? Is the only way around this to change directory?
I'm using bash v4.2.10 on Angstrom Linux if that's relevant.
Quoting the source man page:
source filename [arguments]
....
If filename does not contain a slash, file
names in PATH are used to find the directory containing file-
name.
So... source is trying to search your script.sh in the folders contained in PATH.
If you want to source a file in the current folder use
source ./script.sh
Use an absolute path -- source /root/path/to/some/dir/script.sh -- should sort you.
This can happen when the file is in the wrong format. I FTP'd a Korn Shell script from Windows. I could edit it, but got "not found [No such file or directory]" when I tried to run it. It turned out it was in DOS format, which was indicated in the file name line when I edited it in vi. After I re-FTP'd it, making sure it was being transferred as ASCII, it ran fine.
Related
I am not trying to execute a Bash script from any directory by adding the script to my Path variable.
I want to be able to execute the script from any directory using the directory path to that file ... but the file I want to execute sources other files, that is the problem.
If I am in directory file with two scripts myFunctions.sh and sourceFunctions.sh
sourceFunctions.sh
#!/bin/bash
source ./myFunctions.sh
echoFoo
myFunctions.sh
function echoFoo()
{
echo "foo"
}
I can run myFunctions.sh and foo will print to console, but If I go up a directory and run myFunctions.sh I get error
cd ..
file/sourceFunctions.sh
-bash: doFoo.sh: command not found
Unless I changed source file/myFunctions.sh to source file/myFunctions.sh in sourceFunctions.sh.
So how can I source independent of my working directory so I can run sourceFunctions.sh from any working directory I want?
Thanks
You have the right idea. Doesn't need to be that complicated though:
source `dirname $0`/myFunctions.sh
I often compute "HERE" at the top of my script:
HERE=`dirname $0`
and then use it as needed in my script:
source $HERE/myFunctions.sh
One thing to be careful about is that $HERE will often be a relative path. In fact, it will be whatever path you actually used to run the script, or "." if you provided no path. So if you "cd" within your script, $HERE will no longer be valid. If this is a problem, there's a way (can't think of it off hand) to make sure $HERE is always an absolute path.
I ended up just using a variable of the directory path to the script itself for the source directory
so
#!/bin/bash
source ./myFunctions.sh
echoFoo
becomes
#!/bin/bash
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
source ${SCRIPTPATH}/myFunctions.sh
echoFoo
source
I'm not great in the terminal, and I can't figure out why its returning this. It's probably really obvious so apologies for asking, but the executable file I'm referencing is definitely in that file path, and after researching I can't seem to find an answer:
/home/user/protoc-3.5.1-linux-x86_64/bin/protoc object_detection/protos /*.proto --python_out=.
object_detection/protos/*.proto: No such file or directory
(I can't cd into it as I need to do this in a particular directory)
Thanks
It seems bash is looking for a specific file that has the name "[star]" instead of using this as a wildcard.
I think you might need to use a pipe to get the desired result.
From your command line, it looks like protoc is the executable, located at /home/user/protoc-3.5.1-linux-x86_64/bin/protoc. And that you're giving it two arguments separated by a space: object_detection/protos and /*.proto. If you have spaces in the file path, you'll need to escape them or double-quote them:
protoc object_detection/protos\ /*.proto or
protoc "object_detection/protos /*.proto"
The odd thing is that the error message indicates differently:
object_detection/protos/*.proto: No such file or directory
Or possibly the protoc executable needs the absolute (complete) path for file arguments. If from your current working directory the command ls object_detection/protos/*.proto shows results for you, then you can try running your command like this to use absolute file paths:
/home/user/protoc-3.5.1-linux-x86_64/bin/protoc $PWD/object_detection/protos/*.proto
$PWD is an environment variable that contains your working directory path.
I have a bash script which i want to call from any directory, but i don't want to add the directory it is in to PATH as it is filled with lots of other scripts which will just clutter.
The script in question manipulates environment variables, so i have to source it.
I tried creating an alias
alias aliastoscript="/path/to/script"
source aliastoscript #This does not work says no such file
I also can't copy the script itself to a different location as it depends on the directory structure and other scripts in the directory.
So i tried a symlink to a location already in path:
ln -s /path/to/script /directory/already/in/path/myscript
But this does not work either:
source myscript #says no such file exists
Can anyone suggest how i achieve this? And why does the symlink approach not work?
If it makes any difference, i am using a zsh shell on ubuntu 14.04
EDIT:
The answer given below works, but i also wanted to know why the symlink approach was not working.
Here is the sequence of commands
ln -s /path/to/script /directory/already/in/path/myscript
#Now there is a symlink called myscript in a directory which is in PATH
source myscript arg1 #This throws an error saying no such file myscript,
#but it is not supposed to happen because myscript resides in a directory which is in PATH
EDIT 2:
I just figured what i was doing wrong, the symlink i created, i had used relative paths, totally stupid of me, using absolute paths it worked like a charm.
Try replacing:
alias aliastoscript="/path/to/script"
with:
export aliastoscript="/path/to/script"
You have a $ missing in front of the variable name.
source $aliastoscript
You do not need soft link for the source. The complete file name should work. Better is
source /path/to/script
At first I had
touch $NAME_OF_FILE$DATE.$FILE_EXT
then I changed it to
PATH="Logs/"
touch $PATH$NAME_OF_FILE$DATE.$FILE_EXT
The file is created correctly in the folder, however only echos are being printed in there because says commands are not found like grep, awk, and others.
EDIT: The folder is already created on my desktop
Thanks
Alan
PATH is an environment variable that specifies where executables are located and is used by your shell to look for commands executables (grep, awk, ...). You should not override it in your script.
Try:
MYPATH="Logs/"
touch $MYPATH$NAME_OF_FILE$DATE.$FILE_EXT
To understand what PATH is open a shell and type echo $PATH. You will see it contains the directories where your commands executables are.
I want to add a small script to the linux PATH so I don't have to actually run it where it's physically placed on disk.
The script is quite simple is about giving apt-get access through a proxy I made it like this:
#!/bin/bash
array=( $# )
len=${#array[#]}
_args=${array[#]:1:$len}
sudo http_proxy="http://user:password#server:port" apt-get $_args
Then I saved this as apt-proxy.sh, set it to +x (chmod) and everything is working fine when I am in the directory where this file is placed.
My question is : how to add this apt-proxy to PATH so I can actually call it as if it where the real apt-get ? [from anywhere]
Looking for command line only solutions, if you know how to do by GUI its nice, but not what I am looking for.
Try this:
Save the script as apt-proxy (without the .sh extension) in some directory, like ~/bin.
Add ~/bin to your PATH, typing export PATH=$PATH:~/bin
If you need it permanently, add that last line in your ~/.bashrc. If you're using zsh, then add it to ~/.zshrc instead.
Then you can just run apt-proxy with your arguments and it will run anywhere.
Note that if you export the PATH variable in a specific window it won't update in other bash instances.
You want to define that directory to the path variable, not the actual binary e.g.
PATH=$MYDIR:$PATH
where MYDIR is defined as the directory containing your binary e.g.
PATH=/Users/username/bin:$PATH
You should put this in your startup script e.g. .bashrc such that it runs each time a shell process is invoked.
Note that order is important, and the PATH is evaluated such that if a script matching your name is found in an earlier entry in the path variable, then that's the one you'll execute. So you could name your script as apt-get and put it earlier in the path. I wouldn't do that since it's confusing. You may want to investigate shell aliases instead.
I note also that you say it works fine from your current directory. If by that you mean you have the current directory in your path (.) then that's a potential security risk. Someone could put some trojan variant of a common utility (e.g. ls) in a directory, then get you to cd to that directory and run it inadvertently.
As a final step, after following the solution form proposed by #jlhonora (https://stackoverflow.com/a/20054809/6311511), change the permissions of the files in the folder "~/bin". You can use this:
chmod -R 755 ~/bin
make an alias to the executable into the ~/.bash_profile file and then use it from anywhere or you can source the directory containing the executables you need run from anywhere and that will do the trick for you.
adding to #jlhonora
your changes in ~./bashrc or ~./zshrc won't reflect until you do
source ~./zshrc or source ./bashrc , or restart your pc