Question

This may seem pretty trivial but I am a novice in bash scripting and I could not find the answer elsewhere.

I have mplayer installed on ubuntu 13.04 and I am using it to stream internet radio stations. Normally you need to provide the ip as argument for that:

mplayer http://176.31.113.37:8080

I have created an aliases file in root .bash_aliases where I have the following:

export SOMA="http://173.239.76.147:8090"
export FRESH="http://176.31.113.37:8080"

Now I can play the radio using only the station name: mplayer $FRESH. I was wondering is it possible to get rid of the $ sign also to use the command mplayer FRESH for example.

Thanks!

Was it helpful?

Solution

If you are using variables you need the $ to expand it. I would do this with aliases though, not variables. Consider something like this:

alias mpsoma='mplayer http://192.168.1.1:8090'

Then just type mpsoma to run the full command.

OTHER TIPS

Sure, you can do this; you just need a function with built-in indirection. (In case you don't know, indirection is accessing a value through its name instead of through its value. In Bash, this is done by preceding the variable name with a ! in the parameter expansion.)

##
# Expand variables passed as arguments, otherwise just invoke mplayer normally.
#
mplayer() {
    local first=${!1:-"$1"} # Expand to the indirection of $1 if it exists,
                            # otherwise expand to the value of "$1"
    shift # Drop the 1st parameter. With enough focus, I could probably make this
          # do the indirection on every positional parameter, but it's Friday.
    command mplayer "$first" "$@"
}

If you put echo before the command mplayer part you can see what it's doing:

$ mplayer my name is dug
command mplayer my name is dug
$ my=your
$ mplayer my name is dug
command mplayer your name is dug
$ my=our mplayer my name is dug # You can even do in-place export assignment
command mplayer our name is dug
$ echo $my
your

I found your idea pretty nice so I thought about how this could be solved in another way. What came into my mind was to setup a function inside your ~/.bashrc. The function will be executable like any other command:

# Give the function a nice name - "mplayer" could be problematic
radio()
{
    # Validate the number of parameters passed to our function
    (( $# != 1 )) && {
        printf "%s\n" "Please provide exactly one stream. Quitting."
        return 1
    }

    local stream_alias stream_uri

    # Assign the first parameter to a local variable
    stream_alias="$1"

    # Assign uris to a variable dependent on the value of the
    # parameter passed to the function
    case "$stream_alias" in
        fresh)
            stream_uri="http://176.31.113.37:8080"
        ;;

        soma)
            stream_uri="http://173.239.76.147:8090"
        ;;

        *)
            printf "%s\n" "Unknown stream. Quitting."
            return 1
        ;;
    esac

    mplayer "$stream_uri" && {
        printf "%s\n" "Playing radio station «${stream_alias}@${stream_uri#*\/\/}»."
    }

    return 0
}

This will give you the following results:

$ radio fresh
Playing radio station «fresh@176.31.113.37:8080».

$ radio soma
Playing radio station «soma@173.239.76.147:8090».

$ radio stream1
Unknown stream. Quitting.

Although there is room for improvement - like putting the uris and/or station names into (associative) arrays and maybe adding other features - I think you get the idea As an alternative, in cases where you don't want to put the function inside your .bashrc maybe because you want it to be available to all users, just use a little script and place it at a location which is in each users $PATH (of course you can add a path to it). I use /usr/local/bin for that purpose.

$ cat radio
#!/usr/bin/env bash

# Validate the number of parameters passed to our script
(( $# != 1 )) && {
    printf "%s\n" "Please provide exactly one stream. Quitting."
    exit 1
}

_mplayerStream()
{
    local stream_alias stream_uri

    # Assign the first parameter passed to the function
    # to a local variable
    stream_alias="$1"

    # Assign uris to a variable dependent on the value of the
    # parameter passed to the function
    case "$stream_alias" in
        fresh)
            stream_uri="http://176.31.113.37:8080"
        ;;

        soma)
            stream_uri="http://173.239.76.147:8090"
        ;;

        *)
            printf "%s\n" "Unknown stream. Quitting."
            exit 1
        ;;
    esac

    mplayer "$stream_uri" && {
        printf "%s\n" "Playing radio station «${stream_alias}@${stream_uri#*\/\/}»."
    }

    return 0
}

_mplayerStream "$1"

$ radio soma
Playing radio station «soma@173.239.76.147:8090».

A really nice feature I could imagine would be tab completion showing a list of available streams defined inside the script.

You could make an alias like this:

alias FRESH="mplayer http://176.31.113.37:8080"

Then you can just type

FRESH

Put that line in the file .profile in your login directory and it will be available every time you log in.

Site note: I would use bash aliases in your case. You can write for example in your .bashrc (or better .bash_aliases file if it exists):

alias fresh='mplayer http://176.31.113.37:8080'

Now you can type fresh in your terminal to listen to this internet stream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top