unix

All posts tagged unix

I recently needed to keep a Bash script in a centralized location, with many symbolic links to that script sprinkled throughout my repository. I wanted the script be able to determine both the user’s PWD, as well as the true location of the script. Based on all the different suggestions found online, I created a little test script to see how well each suggestion worked:

#!/bin/bash

echo "\$0"
echo $0
echo ""

echo "pwd -P"
pwd -P
echo ""

echo "pwd -L"
pwd -L
echo ""

echo "which \$0"
which $0
echo ""

echo "readlink -e \$0"
readlink -e $0
echo ""

echo "readlink -e \$BASH_SOURCE"
readlink -e $BASH_SOURCE
echo ""

I put this script (test.sh) in ~/ and then created a symlink to it in a different directory. Here are the results.

My friend JT left a comment below to say that using $BASH_SOURCE is probably the better choice than using $0, since $0 can be changed, and is only set equal to the file name by convention.

Directly calling the script from the same directory (/home/matthew/):

matthew@broderick:~$ ./test.sh
$0
./test.sh

pwd -P
/home/matthew

pwd -L
/home/matthew

which $0
./test.sh

readlink -e $0
/home/matthew/test.sh

Directly calling the script from some other directory (/some/other/directory/):

matthew@broderick:~/some/other/directory$ ~/test.sh
$0
/home/matthew/test.sh

pwd -P
/home/matthew/some/other/directory

pwd -L
/home/matthew/some/other/directory

which $0
/home/matthew/test.sh

readlink -e $0
/home/matthew/test.sh

Creating a symlink to ~/test.sh in ~/some/other/directory, and calling it directly (./test.sh):

matthew@broderick:~/some/other/directory$ ln -s ~/test.sh ./test.sh
matthew@broderick:~/some/other/directory$ ./test.sh
$0
./test.sh

pwd -P
/home/matthew/some/other/directory

pwd -L
/home/matthew/some/other/directory

which $0
./test.sh

readlink -e $0
/home/matthew/test.sh

Creating a symlink to ~/test.sh in ~/some/other/directory, and calling it from yet another location:

matthew@broderick:~/some/other/directory$ ln -s ~/test.sh ./test.sh
matthew@broderick:~/some/other/directory$ cd ~/somewhere/else
matthew@broderick:~/somewhere/else$ ~/some/other/directory/test.sh
$0
/home/matthew/some/other/directory/test.sh

pwd -P
/home/matthew/somewhere/else

pwd -L
/home/matthew/somewhere/else

which $0
/home/matthew/some/other/directory/test.sh

readlink -e $0
/home/matthew/test.sh

Conclusion:
So, it looks like “readlink -e $0” will always return the full, non-symlink, “physical” location of the script (regardless of whether or not symlinks are involved). Looks like “pwd” returns the user’s current working directory reliably.

GNU Screen is a really fantastic piece of software. Screen is a “terminal multiplexer”, that allows you to run and manage several terminal instances from a single terminal window. It’s sort of like how a graphical user interface lets you have multiple graphical application windows running at the same time, allowing you to switch between them at will. Screen is really great when working on a remote server over wifi or any unreliable network connection, as a dropped connection won’t kill off your jobs or close all your shells, you can simply reconnect to the screen instance when you reconnect.

Screen allows you to add a “caption” bar at the bottom of the screen, that sort of acts like a taskbar in a graphical interface. The behavior of the caption bar is controlled by the .screenrc file, and here is what my .screenrc file looks like:
defshell $SHELL
caption always '%{= dg} %H %{G}| %{B}%l %{G}|%=%?%{d}%-w%?%{r}(%{d}%n %t%? {%u} %?%{r})%{d}%?%+w%?%=%{G}| %{B}%M %d %c:%s '

Here is a screenshot of what it looks like:

Basically, the bottom bar displays a bunch of information that you can remove from your prompt. On the left is the hostname (in case you are logged into multiple machines, you won’t get confused this way), then the system load values, and on the far right is the current date and time. The center of the bar is a “task bar” that shows the numbers and configurable names of all the sub-terminals you have in this screen session. (FYI, you can rename your screen session with Control-a A (capital A!), then backspace to remove the default name (usually the name of your shell) and it will update in the “task bar”.)

I have my server set up to server files using Samba (the windows filesharing protocol) now called CIFS. I wanted to use some authentication for the read/write share so here is how to do it.

Make a file called /etc/samba.credentials, owned by root:root, with permissions 0600, with these contents:
username=blah
password=blah

Then add a line like this to your /etc/fstab:
//server/sharename /mount/point cifs auto,credentials=/etc/samba.credentials,iocharset=utf8,file_mode=0777,dir_mode=0777,uid=youruser,gid=yourgroup,nounix 0 0

Then it should be automatically mounted when you login!

set backupcopy=yes
set softtabstop=4
set autoindent
syn on
set cindent
set shiftwidth=4
set shiftround
set expandtab
set formatoptions=t
set textwidth=0
set mouse=a
set bg=dark
map <f5> :set hls!<bar>set hls?<CR>
map <f6> :set paste!<bar>set paste?<CR>

Auto indent and auto syntax highlighting. I use a black background terminal, so the “set bg=dark” optimizes the colors for a dark background. I like 4 spaces for my indenting, no tabs. I use the F5 key to toggle search result highlighting, and F6 to toggle between paste mode (no auto-indent) and no-paste mode.