Showing posts with label CLI. Show all posts
Showing posts with label CLI. Show all posts

Wednesday, October 3, 2012

#!/bin/bash considered harmful

When one writes a shell script there are a variety of shebang lines that could be used:

  • #!/bin/sh
  • #!/usr/bin/env bash
  • #!/bin/bash

or one of many other options.

Of these only the first two are possibly correct.

Using #!/bin/bash is wrong because:

  • Sometimes bash isn't installed.
  • If it is installed, it may not be in /bin
  • If it is in /bin, the user may have decided to set PATH to use a different installation of bash. Using an absolute path like this overrides the user's choices.
  • bash shouldn't be used for scripts intended for portability

If you have bash specific code use #!/usr/bin/env bash. If you want more portable code try using Debian's checkbashism to find instances of non-POSIX compliant shell scripting.

Sunday, March 28, 2010

tsocks with svn - failure

tsocks is a program that will "sockify" any application. It does so by watching the application and rewriting any networking requests to go through the socks server you specify in tsocks.conf.

You can either use tsocks by running tsocks command [arguments] or by running tsocks on followed by the commands you want to run. You turn it off by running tsocks off.

I ran into an annoying error when using tsocks to sockify subversion. I got the error
svn: OPTIONS of '...': could not connect to server (...)
It turns out that using "tsocks svn up" failed this way, but if I tried the second possibility (tsocks on; svn up; tsocks off) it works.
I have no clue why this might be.

Sunday, March 21, 2010

Mercurial Extensions

Mercurial has the ability to load extensions dynamically. All that is required is to modify ~/.hgrc.

In order to add an extension open ~/.hgrc in your preferred text editor. Then look for a line that looks like [extensions]. If you don't find one add it to file. Under this line you can add a large number of extensions. Stock mercurial comes with a number of useful extensions (although none of them are turned on by default).

The following are the ones I found useful.
color  - displays output from some commands in color
fetch - does hg fetch; hg update; hg merge in one command
graphlog - command to view revision graphs from a shell
progress (hgext.progress) - shows progress of some commands

to learn more about extensions type hg help extensions into the command line.

Saturday, December 5, 2009

Using sockets to run VLC in the background or across computers Part 2

This is the "vlc.do" script. This is the main way to interact with vlc once you created a socket.
I also created a few other small "shortcut" scripts that are wrappers to vlc.do to make common tasks easier (such as adding files, pausing, etc)

Lets set up the defaults for options we will be using later

#!/usr/bin/env sh
cmd_to_tell="";
x_mode="";
optdir=~/.vlc_extra;

In vlc_create_sock we put the location of the socket into $optdir/socket. Here we retrieve that location. Keep in mind that we don't look into $optdir/sockets/ directly. I did this because of cleanup problems (the socket file was not always removed when exiting)

socket="$(cat $optdir/socket_name)";

We have three options:
-c "command" This is the command we will be passing to vlc. Try "help" to see them all.
-o dir The optdir. If you want to work on a remote computer or another user's account try changing this.
-x The script uses Xdialog to notify you of what actions took place. This is useful where you map a function to a key on your keyboard and you want visual notification that something took place.

while getopts c:o:x option
do case "$option" in
'c') cmd_to_tell="$OPTARG";;
'o') optdir="$OPTARG";;
'x') x_mode="on";;
esac
done

Here we check to see if you actually told us anything to do - a simple sanity check.

if [ -z "$cmd_to_tell" ]
then
if [ -n "$x_mode" ]
then
Xdialog --icon ~/bin/icons/warning.xpm --infobox "Missing a cmd!" 0 0 2000;
else
echo "Your missing a command..." >/dev/stderr;
fi
return 1;

fi

Here I check to see if the socket actually exists. If it does not exist then I assume VLC is not running and I warn you via Xdialog (if -x is set).

## if no opts give entire line not just cmd_to_tell
if [ -e "$socket" ]
then

Here is the crucial part. nc or netcat has a -U option which lets you write to sockets. VLC will react to any command supplied to it via this file.

echo "$cmd_to_tell"|nc -U $socket
if [ -n "$x_mode" ]
then
Xdialog --title "VLC Remote control" --backtitle "I told vlc to " --no-buttons --icon ~/bin/icons/media-cdrom.xpm --infobox "$cmd_to_tell" 0 0 3000
fi
else
if [ -n "$x_mode" ]
then
Xdialog --icon ~/bin/icons/warning.xpm --infobox "VLC not running!" 0 0 2000;
fi
return 1;
fi

Friday, December 4, 2009

Using sockets to run VLC in the background or across computers Part 1

I wrote a series of scripts to work with VLC.
They work with VLC in the background and let you manipulate the music you listen to via the command line.
With some small changes (change $optdir + chmod $optdir/sockets) you could even get this to work across computers or accounts.

You could download all the scripts I talk about here at The SVN repo viewer or just check them out at:
svn checkout http://stuffpack.googlecode.com/svn/vlc vlc-scripts

Lets get this code to work on any system (if we don't know where sh is)

#!/usr/bin/env sh

Here is a simple function which creates the relevant directory and the working files.
This function is only run if it can't find $optdir

install_me()
{
whomedir="$1";
mkdir "$whomedir";
touch "$whomedir/socket_name";
mkdir "$whomedir/sockets";
}

Here we initialize configuration values.
Afterwords we use the getopts interface to read the command line options.
-c = if you did not properly exit VLC last time vlc_create_sock will refuse to run. This option cleans up
-n = Allows you to use an ncurses interface as well
-o = Allows you to modify $optdir. Changing this to a directory on another user account or on another computer will let you modify remote instances

cleanup="";
ncurse="";
#we default to a directory in your home.
optdir=~/.vlc_extra;
while getopts co:n opt
do
case "$opt" in
'c') cleanup="YES";;
'n') ncurse="YES";;
'o') optdir="$OPTARG";;
'?') exit 1;;
esac
done

If we don't exist let us install ourself

if [ ! -d "$optdir" ]
then
install_me "$optdir";
fi

We now work with the options you gave us....
Print "Yeah!" if we will ignoring current instances

[ -n "$cleanup" ] && echo "Yeah!";
base="$(basename $0)";

Here we look to see if VLC is currently running. This prevents us from stopping a current instance. Using the option "-c" will forcefully end current instances. It does not skip the check

current_sock="$(cat $optdir/socket_name)";
if [ -n "$cleanup" ]
then
# exit program if currently running
vlc.do -c quit;
# remove the socket file (not deleted before if program not running)
rm $current_sock;
# empty the current socket file...
:>$optdir/socket_name;
fi

Here we tell you if vlc is current running. It requires Xdialog (and therefore X). I did these because of how I use the script. It isn't to difficult to change to detect X/no X or even just make it an option. This is on my list of things to do (issue 9).

if [ -e "$current_sock" ]
then
Xdialog --icon ~/bin/icons/warning.xpm --infobox "VLC already running...." 0 0 2000;
return 1;
fi

We now know that we are all set to start a new session.
We first create a file in $optdir/sockets. This is because we will be using the "rc-unix" interface of vlc. This allows you to run vlc in the background and then close the terminal.

TMPFILE=$(mktemp $optdir/sockets/XXXXXX);
#we can't operate if the file exists....
rm "$TMPFILE";
echo $TMPFILE;
echo "$TMPFILE">$optdir/socket_name;

Choose the default options to run VLC with. If we specified "-n" also include an ncurses control to the same session.

Lets explain each of these options one by one:
--rc-unix This option tells VLC where to put the unix socket that we will be communicating with.
--rc-fake-tty This option is required by certain Linux distros or when run by some Terminal emulators
-L Loop through the music once you reach the last one - maybe I should make this into an option
--no-media-library Not actually required
--volume I let vlc run at max volume and have the operating system or speaker control what comes out.
-d Run as a daemon.

# -L == loop; -d == deamon;
vlc_opts="--rc-unix "$TMPFILE" --rc-fake-tty -L --no-media-library -d --volume 1024";
if [ -n "$ncurse" ]
then
vlc --intf rc --extraintf ncurses $vlc_opts;
else
vlc --intf rc $vlc_opts;
fi

It worked! Lets return 0!

return 0;

In my next post I'll explain vlc.do, vlc.done, and the other control scripts.