What does it mean in Unix when you use . ./<filename>?
Thanks for the help
". ./?" would try and run a program called '?' which would reside in the current directory and it would be run in the current shell.
The first dot means 'run in current shell' (rather than spawning a new one)., the './' means 'current directory' and '?' would mean an executable file called '?' would have to exist.
Running . on a filename runs the commands in the file as though you typed them at the shell command prompt. Unlike a shell script, environment variable (and similar) changes produced by the file persist beyond running the file; the changes made by a shell script are reverted when the script finishes.
The . or source command reads the given file into the current shell. I.e. basically the given file is a shellscript which is run by typing . filename, however using . (or source, which is equivalent) differs from running the file ordinarily as a shell script in that it doesn't spawn a subshell and thus retains variables that are exported by the script. So if the script sets and exports variables, they will still be set when the script finishes.
source or . take a file as parameter. Every line of code in that file is executed. So I don't think that
. ./
would work.
$ . ./
-bash: .: ./: is a directory
$ echo "echo Hello" > out
$ . out
Hello
$ source out
Hello
Related
Going through a UNIX shell script, I noticed that the path to the current working directory is being obtained using the following
BASE_DIR=$( readlink -e `dirname $0` )
the command 'pwd' also returns the same results. Is there a reason to use the above instead of pwd ?
The above returns the location of the file being executed, not the pwd, which can differ.
I want to execute an external program from within R, and I added the directory path of the executable to ~/.bashrc. When I type echo $PATH in the terminal, everything looks fine, but when I execute system("echo $PATH") or Sys.getenv("PATH") in R, a lot of paths are missing. Can someone explain to me what I'm doing wrong?
Maybe use /etc/bash.bashrc instead? Also make sure that system() treats this as login shell and does full initialization. Worst case, place a script in, say, /usr/local/bin and set PATH in the script.
I'm writing a script that will print the file names of every file in a subdirectory of my home directory. My code is:
foreach file (`~/.garbage`)
echo "$file"
end
When I try to run my script, I get the following error:
home/.garbage: Permission denied.
I've tried setting permissions to 755 for the .garbage directory and my script, but I can't get over this error. Is there something I'm doing incorrectly? It's a tcsh script.
Why not just use ls ~/.garbage
or if you want each file on a separate line, ls -1 ~/.garbage
backtic will try to execute whatever is inside them. You are getting this error since you are giving a directory name within backtic.
You can use ls ~/.garbage in backtics as mentioned by Mark or use ~/.garbage/* in quotes and rely on the shell to expand the glob for you. If you want to get only the filename from a full path; use the basename command or some sed/awk magic
I have the following script
#!/usr/bin/Rscript
print ("shebang works")
in a file called shebang.r. When I run it from command line using Rscript it works
$ Rscript shebang.r
but when I run it from the command line alone
$ shebang.r
It doesn't work. shebang.r command not found.
If I type (based on other examples I've seen)
$ ./shebang.r
I get permission denied.
Yes, Rscript is located in /usr/bin directory
Make the file executable.
chmod 755 shebang.r
In addition to Sjoerd's answer... Only the directories listed in the environment variable PATH are inspected for commands to run. You need to type ./shebang.r (as opposed to just shebang.r) if the current directory, known as ., is not in your PATH.
To inspect PATH, type
echo $PATH
To add . to PATH, type
export PATH="$PATH:."
You can add this line to your ~/.bashrc to make it happen automatically if you open a new shell.
At a unix command line, what's the difference between executing a program by simply typing it's name, vs. executing a program by typing a . (dot) followed by the program name? e.g.:
runme
vs.
. runme
. name sources the file called name into the current shell. So if a file contains this
A=hello
Then if you sources that, afterwards you can refer to a variable called A which will contain hello. But if you execute the file (given proper execution rights and #!/interpreterline), then such things won't work, since the variable and other things that script sets will only affects its subshell it is run in.
Sourcing a binary file will not make any sense: Shell wouldn't know how to interpret the binary stuff (remember it inserts the things appearing in that file into the current shell - much like the good old #include <file> mechanism in C). Example:
head -c 10 /dev/urandom > foo.sh; . foo.sh # don't do this at home!
bash: �ǻD$�/�: file or directory not found
Executing a binary file, however, does make a lot of sense, of course. So normally you want to just name the file you want to execute, and in special cases, like the A=hello case above, you want to source a file.
Using "source" or "." causes the commands to run in the current process. Running the script as an executable gives it its own process.
This matters most if you are trying to set environment variable in current shell (which you can't do in a separate process) or want to abort the script without aborting your shell (which you can only do in a separate process).
The first executes the command. The second is shorthand for including a shell script inside another.
This syntax is used to "load" and parse a script. It's most useful when you have a script that has common functionality to a bunch of other scripts, and you can just "dot include" it. See http://tldp.org/LDP/abs/html/internal.html for details (scroll down to the "dot" command).
Running "runme" will create a new process which will go on its merry little way and not affect your shell.
Running ". runme" will allow the script "runme" to change your environment variables, change directories, and all sorts of other things that you might want it to do for you. It can only do this because it's being interpreted by the shell process that's already running for you. As a consequence, if you're running bash as your login shell, you can only use the "." notation with a bash script, not (for example) a binary on C shell script.