Simple applescript to pass on commands

I need a very simple Applescript that will allow me to pass on commands as arguments from the command line.


What I'm ultimately needing is to connect HDPVRCapture to my ZephIR blaster. HDPVRCapture can easily be configured to control any IR Blaster that can be controlled from the command line and ZephIR can easily be controlled using Applescript.


To change the channel directly, you simply (this is an example from their website) --


tell application "ZephIR"


fire zephir command "3" of component "ComCast Cable DCT 7001"

fire zephir command "4" of component "ComCast Cable DCT 7001"

fire zephir command "5" of component "ComCast Cable DCT 7001"

fire zephir command "enter" of component "ComCast Cable DCT 7001"


end tell


What I'm needing is a script that will accept channels as a command line argument as opposed to hard coding.


i.e. -- a script that does the "fire zephir command" and the "of component abc" but where the actual command comes from the argument attached when the script is run from the command line.


I'm sure this is a stupid question and I'll probably kick myself with how easy it ends up being, but for the life of me I'm stuck.


Any help would be greatly appreciated,

Thank you very much in advance.

OS X Mountain Lion (10.8.4)

Posted on Aug 11, 2013 9:08 PM

Reply
13 replies

Aug 11, 2013 10:37 PM in response to red_menace

That's very close, but it would need to be something I could call using osax from the command line.


i.e. -- Instead of choosing the numbers from a list, I would need to just have it accept whatever was fed to it as a command line argument *as* the channel (obviously the only arguments would be one, two, three, or four digits).


Despite their example, I don't even have to hit "enter" because it can be configured to enter that automatically after a seconds delay (mimicking how you might hit numbers on a control and the short time it would take your thumb to hit "enter", etc.)

Aug 12, 2013 7:53 AM in response to MJMullinII

You should create a modified version of the website example script that looks like so:


on run argv


set componentName to item 1 of argv


tell application "ZephIR"

fire zephir command "3" of component componentName

fire zephir command "4" of component componentName

fire zephir command "5" of component componentName

fire zephir command "enter" of component componentName

end tell

end run


This adds a run block to catch arguments in the argv variable and extracts the component name from that variable. You can then call this script from the command line this way:


osascript /path/to/script.scpt 'ComCast Cable DCT 7001'


Should do the trick. if you want to handle multiple components in one call the script needs some minor adjustments.

Aug 12, 2013 7:59 AM in response to MJMullinII

#!/usr/bin/env bash

usage()
{
    echo ""
    echo "Usage:  ${0##*/}  nnn"
    echo ""
    echo "        Takes the up to 3 digit channel and passes it to ZephIR"
    echo ""
    exit
}

shopt -s extglob        # enable extended globs +(...), *(...), etc...
if [[ $1 != +([0-9]) || ${#1} -gt 3 ]]; then
    usage
    exit
fi

chan=$1
[[ ${#chan} -lt 3 ]] && chan=0${chan}
[[ ${#chan} -lt 3 ]] && chan=0${chan}

d1=${chan%??};  # remove last 2 digits
chan=${chan#?}; # remove first digit - chan now 2 digits
d2=${chan%?};   # remove last digit of remaining 2
d3=${chan#?};   # remove first digit of remaining 2

osascript -e "
    tell application \"ZephIR\"
        fire zephir command \"${d1}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"${d2}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"${d3}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"enter\" of component \"ComCast Cable DCT 7001\"
    end tell
"

Aug 14, 2013 10:24 PM in response to BobHarris

First I would like to say thank you very much, your script did exactly what I had in mind. I thought it would work perfectly as it did what the creators of HDPVRCapture said was required of an external channel change script.


However, upon trying it with the program (worked fine from the command line), the program did register the script was working.


Again, I knew your script worked because I'd already used it manually from the command line myself.


It turns out (this after writing an email to the authors of HDPVRCapture and asking their opinion of what the problem was), it doesn't simply call the script and then the channel, apparently it calls the script (I named your shell script "ZephIR.sh") *then* it uses the argument "-c" and then inputs the channel.


NO WHERE on their website nor in any of the documentation did it describe the requirement of any arguments needing to be accepted by the shell script.


I say that because it makes me feel stupid having to ask for help a second time when if I'd *known* about the requirement I certainly would have included it in the equation to begin with.


However, *may* I ask for help one last time and ask how one might modify the otherwise perfect 😝 shell script above to allow for the use of an argument " -c " before the channel is input?


Thank you very much in advance.

Aug 15, 2013 12:37 AM in response to MJMullinII

Hello


You mean it invokes the shell script a.sh with argument 123 by -


/bin/bash -c "$(cat a.sh)" 123


instead of -


./a.sh 123


?


If so, you need to change $1 to $0 in the given bash script because the first argument is assigned to $0, not $1, if -c option is used.

See bash(1) manpage for detalis. Extract follows -


OPTIONS


-c string If the -c option is present, then commands are read from

string. If there are arguments after the string, they are

assigned to the positional parameters, starting with $0.



Regards,

H

Aug 15, 2013 5:36 AM in response to MJMullinII

It turns out (this after writing an email to the authors of HDPVRCapture and asking their opinion of what the problem was), it doesn't simply call the script and then the channel, apparently it calls the script (I named your shell script "ZephIR.sh") *then* it uses the argument "-c" and then inputs the channel.


I'm guessing that they are invoking your script as follows:


ZephIR.sh -c 345


Where the '-c' is for 'channel'. Does this sound about right?


If that is the case, then I would modify my example as follows (NOTE: the script now requires -c 123 were as before it just took the channel):


#!/usr/bin/env bash

usage()
{
    echo ""
    echo "Usage:  ${0##*/}  -c nnn"
    echo ""
    echo "        -c nnn - passes channel nnn to ZephIR."
    echo "        -h     - display this usage message."
    echo ""
}

normalize_channel()
{
    typeset chan=$1
    [[ ${#chan} -lt 3 ]] && chan=0${chan}
    [[ ${#chan} -lt 3 ]] && chan=0${chan}

    echo ${chan}
}

shopt -s extglob        # enable extended globs +(...), *(...), etc...
if [[ $# = 0 ]]; then
    # no arguments passed, print usage
    usage
    exit 1
fi
# loop through all the arguments looking for -letter options
while [[ X$1 = X-* ]]
do
    if [[ X$1 = X-c ]]; then
        # -c so the next argument should be the channel number.
        shift # move channel number from $2 to $1
        if [[ $1 != +([0-9]) || ${#1} -gt 3 ]]; then
            # channel number is not all digits.
            usage
            exit 1
        fi
        chan=$(normalize_channel $1)
    elif [[ X$1 = X-h ]]; then
        # -h asks for help, so print the usage.
        usage
        exit
    else
        echo ""
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        usage
        exit 1
    fi
    shift       # shift all the arguments down one number position.
done

if [[ -z "${chan}" || $# != 0 ]]; then
    # make sure we have received a channel number.
    usage
    exit 1
fi

d1=${chan%??};  # remove last 2 digits
chan=${chan#?}; # remove first digit - chan now 2 digits
d2=${chan%?};   # remove last digit of remaining 2
d3=${chan#?};   # remove first digit of remaining 2

osascript -e "
    tell application \"ZephIR\"
        fire zephir command \"${d1}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"${d2}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"${d3}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"enter\" of component \"ComCast Cable DCT 7001\"
    end tell
"

Aug 15, 2013 5:52 AM in response to MJMullinII

If I got the -c usage wrong, then maybe HDPVRCapture is confusing both of us 🙂


If I understand correctly you have a ZephIR IR Blaster that will change channels from your Mac. You are then trying to get HDPVRCapture to use the ZephIR to set the channel on your Comcast box. Then I assume HDPVRCapture will try to capture the video on the specified channel.


If my script is everything you need, Great!


If there is some other HDPVRCapture side effect that needs to be addressed, it would help if you could find the HDPVRCapture instructions that describe calling ZephIR, as it is possible they can pass other options besides -c. Such as telling the device to power on/power off using a different -letter option. Or tell the ZephIR to switch to a different device to be controlled.


I'm just guessing, but based on my experience, software developers do not add a -c option unless there are other options they want to pass that will do different things.

Aug 15, 2013 12:41 PM in response to BobHarris

I'll post the exact response I got when I sent them a copy of your script (your initial script, the one I thought satisfied the programs requirements) --


The script is actually passed three arguments:


<script> -c <channel_number> -d <recording duration in seconds> -f <file being written to>


Frankly, as it's listed as a "channel changing script" in the preferences, I don't understand why it does anything more than that.


It would seem that sense this is a 100% Mac OS X program, they would simply use standard Applescript all the way around and avoid the headache.


I didn't think (again, I guess I shouldn't be "thinking" at all sense I know nothing about shell scripts 😝 ) the following two arguments mattered so long as the first two were met. I just tried your last idea, and it behaves exactly as before (i.e. -- it starts recording fine, but it does *not* touch the ZephIR or change the channel).


Frankly, I'm thinking now that it might be easier to create a simple static Applescript hard coded to change to a particular channel and just have iCal call it whenever it triggers a recording. I had no idea something that seemed so simple would be so involved for all concerned and, again, thank everyone for there efforts.

Aug 16, 2013 6:28 AM in response to MJMullinII

The following should accept -d and -f option, but will ignore them.


If there are Applescript commands to handle duration and output file, we could incorporate them into the osascript section.


#!/usr/bin/env bash

usage()
{
    echo ""
    echo "Usage:  ${0##*/}  -c nnn"
    echo ""
    echo "        -c nnn  - passes channel nnn to ZephIR."
    echo "        -h      - display this usage message."
    echo ""
    echo "        -d nnn  - Ignored (recording duration)"
    echo "        -f file - Ignored (output file)"
    echo ""
}

normalize_channel()
{
    typeset chan=$1
    [[ ${#chan} -lt 3 ]] && chan=0${chan}
    [[ ${#chan} -lt 3 ]] && chan=0${chan}

    echo ${chan}
}

shopt -s extglob        # enable extended globs +(...), *(...), etc...
if [[ $# = 0 ]]; then
    # no arguments passed, print usage
    usage
    exit 1
fi
# loop through all the arguments looking for -letter options
while [[ X$1 = X-* ]]
do
    if [[ X$1 = X-c ]]; then
        # -c so the next argument should be the channel number.
        shift # move channel number from $2 to $1
        if [[ $1 != +([0-9]) || ${#1} -gt 3 ]]; then
            # channel number is not all digits.
            usage
            exit 1
        fi
        chan=$(normalize_channel $1)
    elif [[ X$1 = X-h ]]; then
        # -h asks for help, so print the usage.
        usage
        exit
    elif [[ X$1 = X-d ]]; then
        # this script does not know how to handle "recording duration in
        # seconds", so it is ignored.
        shift
    elif [[ X$1 = X-f ]]; then
        # this script does not know how to handle "recording duration in
        # seconds", so it is ignored.
        shift
    else
        echo ""
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        echo "*** Unknown option: $1 ***"
        usage
        exit 1
    fi
    shift       # shift all the arguments down one number position.
done

if [[ -z "${chan}" || $# != 0 ]]; then
    # make sure we have received a channel number.
    usage
    exit 1
fi

d1=${chan%??};  # remove last 2 digits
chan=${chan#?}; # remove first digit - chan now 2 digits
d2=${chan%?};   # remove last digit of remaining 2
d3=${chan#?};   # remove first digit of remaining 2

osascript -e "
    tell application \"ZephIR\"
        fire zephir command \"${d1}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"${d2}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"${d3}\" of component \"ComCast Cable DCT 7001\"
        fire zephir command \"enter\" of component \"ComCast Cable DCT 7001\"
    end tell
"

Aug 16, 2013 11:17 PM in response to BobHarris

And *YOU* sir are a steely-eyed missile man! 😀


Works perfectly...does *EXACTLY* what I had in mind.


I will tell of your wisdom far and wide so that all members of the kingdom who seek guidance shall know where to acquire it 😝😁!


The only contribution I will make (in the event someone reads this post and looks to do likewise with their hardware, etc) is that you need -- and this was the secret sauce that brought everything together -- to manually open the


net.steventoth.HDPVRCapture.plist


file in your ~/Library/Preferences and manually (there doesn't seem to be an option in the GUI) and change the


IRBlasterMinDigits


from "4" to "3" digits.


The shell script above might be able to be modified to accept 4 digits directly *however* my DirecTV STB has always become confused when given that many digits (I don't subscribe to any packages that require more than 3 digits in any event).

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Simple applescript to pass on commands

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.