Shadrack Posted December 11, 2005 Share Posted December 11, 2005 Here are some terminal shell tips I've compiled together. Most of the information came from googling around and fooling around. I'm in the process of better understanding Applescript, so hopefully more content is to come. This is a short guide on simplifying the Terminal to Mac OS GUI interface. I personally find that I can work faster using a well refined shell environment then i can by clicking around in the Finder. I will, however, admit that using a shell isn't for everyone. I found while initially using the Darwin shell that there was a strong disconnection between that shell environment and the graphical world that is the Mac OS. I could identify the connection between where things were from a finder window to a Unix path in Darwin. I could use the Unix commands I knew from using various Unix versions and Linux after all these years (ls, rm, cat, echo.) Something else I could do "right out of the box" was drag and drop a file from a Finder window into the terminal and have it copy the full unix path of the file wherever my cursor was. Cool. With a little Applescript and Bash Shell Scripting, I was able to piece together a very usable Shell interface and can work quickly in it to get jobs done. Introductory Notes You can assume that any line in a code block that starts with a "$ " is a shell prompt, and characters after are typed directly into the shell. Example: $ echo this is a test Explicitly means: i typed "echo this is a test" into the Terminal at a shell prompt. I am using Bash as my default shell, and therefore my shell scripts only run in that shell environment. You can find out what shell you are using by typing: $ echo $SHELL If you are not currently using Bash and want to switch, goto Terminal->Preferences and select "Execute this command (specify complete path):" and type the path "/bin/bash". You may also want to change your default window settings to look prettier. "Courier New 18pt" with Anti-aliasing is what I use for my font. The default looks like crap. A nice background and transparency effect can make it look a lot more like a part of the Mac OS system. This guide assumes you are familiar with working in a shell environment and are comfortable with shell commands. It is beyond the scope of this guide to teach you how to open and edit a file in the shell. open -a TextEdit /path/to/file This might get you somewhere if you are loss, but if that be the case you should probably read up on a general howto use a Unix shell. There are about a million out there. I prefer Vim/gVim over TextEdit, but you may or may not have it installed or are interested in trying it. ~/bin I have my own bin folder in my home folder that I put all my scripts and executables in. Avoid using the system bin (/bin) for your own creations. .profile .profile is a Bash file that is in your home directory (/Users/$USER/ or simply ~/) and is run whenever Terminal is opened. Here is my final .profile: #Mac OS Programs aliases alias gvim="open -a gvim" alias photoshop="open -a \"adobe photoshop cs\"" alias illustrator="open -a \"illustrator cs\"" alias safari="open -a safari" alias firefox="open -a firefox" alias sedit="open -a \"/Applications/AppleScript/Script Editor.app/\"" alias preview="open -a preview" alias word="open -a \"Microsoft Word\"" #interesting list modes alias list="ls -CF" alias lam="ls -al | more" #Sometimes it is better to move folders and files into the trash #rather then "rm"ing them. alias trash="osascript ~/bin/trash.scpt" #iTunes involves some cleverness for speed reasons function itunes () { osascript ~/bin/itunes.scpt $* & } #add my personal bin folder to the path export PATH=$PATH:~/bin #set my super cool shell prompt PS1="\n\[\033[0;37m\].: \[\033[1;33m\]\w\[\033[0;37m\] :: [\[\033[0;37m\]\t \@\[\033[0;37m\]] \n\h [\!]: \[\033[1;37m\]" The aliases leverage the long strings that you use over and over again, such as "open -a..." which opens a particular application that you have in either /Applications or ~/Applications. Sometimes you have to give it a very specific path to the .app file, other times you can just give the name. It takes some fooling around, and some investigation work on your part to get right. Now I can type: $ photoshop neat_graphic.jpg and Adobe Photoshop will open with the neat_graphic.jpg. If it is already open, then it is brought to the front. AppleScript Applescript can be executed from the shell using the "osascript" utility. You should use "Script Editor" and compile your code, but it should be able to read any text file and execute the code within. Here is my ~/bin/trash.scpt on run argv set file_path to item 1 in argv set theMacOSXPath to (POSIX file file_path) as string tell application "Finder" to delete theMacOSXPath as alias end run I wrote it because rm -R /folder, scares me :D. And I'm already using the trash so much! If you plan to pass parameters from the shell to the script, you must wrap your code up in a "on run argv" statement. The Unix file path might also need to be converted to a Mac OS X path and vise versa depending on what you are doing. More on that here. Here is my ~/bin/itunes.scpt on run argv tell application "iTunes" if not (exists playlist "Script Playlist") then make new playlist with properties {name:"Script Playlist"} else delete every track of playlist "Script Playlist" repeat while (number of tracks of playlist "Script Playlist") > 0 delay 0.1 -- wait for the library to clear out end repeat end if set play_string to "" repeat with ThisItem in argv set play_string to play_string & " " & ThisItem end repeat set trax to (search library playlist 1 for play_string) set p to false --duplicate item 1 of trax to playlist "Script Playlist" repeat with t in trax try duplicate t to playlist "Script Playlist" if not p then repeat while (number of tracks of playlist "Script Playlist") = 0 delay 0.1 -- wait for track to be added end repeat play track 1 of playlist "Script Playlist" set p to true end if end try end repeat end tell end run Source This, along with the function itunes() declared in my .profile allow me to type: $ itunes royksopp at the shell prompt, and have itunes look up "royksopp" and plays the first one. The function is declared so that the "&" operator can be used and my shell prompt is returned immediately, instead of waiting for iTunes to finish loading all the songs. If there were 100's of songs in the query, it could take awhile. I'm still working on an implementation that detects if the input argument is an actual file, and tells iTunes to play that file. But something is wrong with the file detection argument (-e) of the "test" (or [) program for bash (i think). This is what I came up with in a shell script: #!/bin/bash if [ -e $1 ]; then open -a "itunes" $1 else osascript ~/bin/itunes.scpt $1 & fi Haven't had much luck with it. be a tab ninja :shiftyninja: and other misc shell tips What I like about the shell is the auto-complete with the "tab" key. Try it out to see what I'm talking about. That is what I think makes it faster to navigate around in the shell as oppose to a Finder window. "touch" is useful for creating a specific file. Sometimes applescript or the open command will throw back "file not found" or something similar if you are trying to open a file that doesn't exist yet in a program. Try: $ touch mynewfile.doc $ word mynewfile.doc if you have any problems. Well..thats a start, anyway. Hopefully it was helpful. Comments? Questions? -Shadrack Link to comment Share on other sites More sharing options...
Shadrack Posted December 11, 2005 Author Share Posted December 11, 2005 Here is an alarm and sleep script, I modified from here. wakeup.sh #!/bin/sh # This script plays music and speaks to you to wake you up # after a specified number of hours & minutes # Functions #-------------------------------- music_app="iTunes" speak_message() { message="$*" echo "say \"$message\"" | /usr/bin/osascript } speak_time() { hour=`date "+%H"` time=`date "+%I %M"` if [ $hour -le 11 ]; then message="The time is now $time A-M" else message="The time is now $time P-M" fi speak_message $message } start_music() { # artist="$*" #echo "tell application \"$music_app\" to play (some track of playlist \"Library\" whose artist is \"$artist\")" | /usr/bin/osascript echo "tell application \"$music_app\" to play (some track of playlist \"Alarm\")" | /usr/bin/osascript } pause_music() { echo "tell application \"$music_app\" to pause" | /usr/bin/osascript } resume_music() { echo "tell application \"$music_app\" to play" | /usr/bin/osascript } fade_in_volume() { # sound_initial_volume=0 sound_increment_amount=2 sound_increment_rate=.1 the_volume=$sound_initial_volume echo "tell application \"itunes\" to set the sound volume to $sound_initial_volume" | /usr/bin/osascript while [ $the_volume -lt 100 ] do sleep $sound_increment_rate the_volume=`expr $the_volume + $sound_increment_amount` echo "tell application \"iTunes\" to set the sound volume to $the_volume" | /usr/bin/osascript done } fade_in_volume_quickly() { sound_initial_volume=35 sound_increment_amount=5 sound_increment_rate=.01 the_volume=$sound_initial_volume twice_initial_volume=`expr $sound_initial_volume \* 2` echo "tell application \"itunes\" to set the sound volume to $sound_initial_volume" | /usr/bin/osascript while [ $the_volume -lt 100 ] do sleep $sound_increment_rate the_volume=`expr $the_volume + $sound_increment_amount` echo "tell application \"iTunes\" to set the sound volume to $the_volume" | /usr/bin/osascript done } # Command-line arguments #-------------------------------- if [ $# -lt 1 ]; then echo "Usage: $0 hours [minutes]" exit fi hours=$1 minutes=0 if [ $# -gt 1 ]; then minutes=$2 fi ack_msg="I will wake you up in $hours hours and $minutes minutes" speak_time speak_message $ack_msg # Sleep until it's time to wakeup #-------------------------------- delay_seconds=`expr $hours \* 3600 + $minutes \* 60` sleep $delay_seconds name=$USER message0="Time to get your lazy ass out of bed and get to work!" message1="Wake up!" message2="You are going to be late." message4="Think about breakfast!" message3="Time to Wake Up, Knickerbocker." announce_delay=400 run_for=7200 has_run_for=0 # Deliver wake-up message #-------------------------------- fade_in_volume & start_music $artist1 while [ $has_run_for -lt $run_for ] do sleep $announce_delay has_run_for=`expr $has_run_for + $announce_delay` fade_in_volume_quickly & sleep .5 speak_time random_message=message`expr $RANDOM % 4` eval random_message=\$$random_message speak_message $random_message done pause_music My modification includes random messages, and cool fade-in and fade-out. Usage "wakeup.sh hours mins". Example: $ ./wakeup.sh 0 30 To wake up in 30 minuets. Also be sure to have a Playlist named "Alarm" or change the script to a playlist that better suits you. I was using "Most Recently Played" smartlist, but found the techno songs annoying in the morning. Be sure to also "chmod 755 wakeup.sh" Slightly modified version creates a sleep script: sleep.sh #!/bin/sh # Functions #-------------------------------- music_app="iTunes" speak_message() { message="$*" echo "say \"$message\"" | /usr/bin/osascript } speak_time() { hour=`date "+%H"` time=`date "+%I %M"` if [ $hour -le 11 ]; then message="The time is now $time A-M" else message="The time is now $time P-M" fi speak_message $message } start_music() { # artist="$*" #echo "tell application \"$music_app\" to play (some track of playlist \"Library\" whose artist is \"$artist\")" | /usr/bin/osascript echo "tell application \"$music_app\" to play (some track of playlist \"Recently Played\")" | /usr/bin/osascript } pause_music() { echo "tell application \"$music_app\" to pause" | /usr/bin/osascript } # Command-line arguments #-------------------------------- if [ $# -lt 1 ]; then echo "Usage: $0 hours [minutes]" exit fi hours=$1 minutes=0 if [ $# -gt 1 ]; then minutes=$2 fi ack_msg="I will stop playing music in $hours hours and $minutes minutes" speak_time speak_message $ack_msg # Sleep until it's time to wakeup #-------------------------------- delay_seconds=`expr $hours \* 3600 + $minutes \* 60` sleep $delay_seconds pause_music Usage should be fairly obvious. You could be proactively lazy and create aliases for the commands in your .profile. You could also add wakeup.sh to your /etc/crontab file to schedule an alarm monday-friday or whatever. $ sudo vim /etc/crontab to open crontab (you need root privileges). Does anyone know how to open an .app type application with "root" privileges? sudo open -a .... doesn't work like expected. crontab: 00 23 * * 0-4 shadrack /Users/shadrack/bin/wakeup.sh 8 15 This executes the script at 11 PM sunday-through thursday to wake me up at 7:15am monday-friday. You can learn more about cron tab by typing: $ man crontab or googling. There is probably also a Mac OS applet that handles setting up cron jobs. -shad Link to comment Share on other sites More sharing options...
matocaster Posted December 11, 2005 Share Posted December 11, 2005 There was an iTunes status script available on MacOSX Hints; #!/bin/sh # #################################### # iTunes Command Line Control v1.0 # written by David Schlosnagle # created 2001.11.08 #################################### showHelp () { echo "-----------------------------"; echo "iTunes Command Line Interface"; echo "-----------------------------"; echo "Usage: `basename $0` <option>"; echo; echo "Options:"; echo " status = Shows iTunes' status, current artist and track."; echo " play = Start playing iTunes."; echo " pause = Pause iTunes."; echo " next = Go to the next track."; echo " prev = Go to the previous track."; echo " mute = Mute iTunes' volume."; echo " unmute = Unmute iTunes' volume."; echo " vol up = Increase iTunes' volume by 10%"; echo " vol down = Increase iTunes' volume by 10%"; echo " vol # = Set iTunes' volume to # [0-100]"; echo " stop = Stop iTunes."; echo " quit = Quit iTunes."; } if [ $# = 0 ]; then showHelp; fi while [ $# -gt 0 ]; do arg=$1; case $arg in "status" ) state=`osascript -e 'tell application "iTunes" to player state as string'`; echo "iTunes is currently $state."; if [ $state = "playing" ]; then artist=`osascript -e 'tell application "iTunes" to artist of current track as string'`; track=`osascript -e 'tell application "iTunes" to name of current track as string'`; echo "Current track $artist: $track"; fi break;; "play" ) echo "Playing iTunes."; osascript -e 'tell application "iTunes" to play'; break;; "pause" ) echo "Pausing iTunes."; osascript -e 'tell application "iTunes" to pause'; break;; "next" ) echo "Going to next track."; osascript -e 'tell application "iTunes" to next track'; break;; "prev" ) echo "Going to previous track."; osascript -e 'tell application "iTunes" to previous track'; break;; "mute" ) echo "Muting iTunes volume level."; osascript -e 'tell application "iTunes" to set mute to true'; break;; "unmute" ) echo "Unmuting iTunes volume level."; osascript -e 'tell application "iTunes" to set mute to false'; break;; "vol" ) echo "Changing iTunes volume level."; vol=`osascript -e 'tell application "iTunes" to sound volume as integer'`; if [ $2 = "up" ]; then newvol=$(( vol+10 )); fi if [ $2 = "down" ]; then newvol=$(( vol-10 )); fi if [ $2 -gt 0 ]; then newvol=$2; fi osascript -e "tell application \"iTunes\" to set sound volume to $newvol"; break;; "stop" ) echo "Stopping iTunes."; osascript -e 'tell application "iTunes" to stop'; break;; "quit" ) echo "Quitting iTunes."; osascript -e 'tell application "iTunes" to quit'; exit 1;; "help" | * ) echo "help:"; showHelp; break;; esac done I added the ability to execute your script from it :cool:, here we go; #!/bin/sh # #################################### # iTunes Command Line Control v1.0 # written by David Schlosnagle # created 2001.11.08 #################################### showHelp () { echo "-----------------------------"; echo "iTunes Command Line Interface"; echo "-----------------------------"; echo "Usage: `basename $0` <option>"; echo; echo "Options:"; echo " status = Shows iTunes' status, current artist and track."; echo " play = Start playing iTunes."; echo " pause = Pause iTunes."; echo " next = Go to the next track."; echo " prev = Go to the previous track."; echo " band = Play the first song with this name."; echo " mute = Mute iTunes' volume."; echo " unmute = Unmute iTunes' volume."; echo " vol up = Increase iTunes' volume by 10%"; echo " vol down = Increase iTunes' volume by 10%"; echo " vol # = Set iTunes' volume to # [0-100]"; echo " stop = Stop iTunes."; echo " quit = Quit iTunes."; } if [ $# = 0 ]; then showHelp; fi while [ $# -gt 0 ]; do arg=$1; case $arg in "status" ) state=`osascript -e 'tell application "iTunes" to player state as string'`; echo "iTunes is currently $state."; if [ $state = "playing" ]; then artist=`osascript -e 'tell application "iTunes" to artist of current track as string'`; track=`osascript -e 'tell application "iTunes" to name of current track as string'`; echo "Current track $artist: $track"; fi break;; "play" ) echo "Playing iTunes."; osascript -e 'tell application "iTunes" to play'; break;; "pause" ) echo "Pausing iTunes."; osascript -e 'tell application "iTunes" to pause'; break;; "next" ) echo "Going to next track."; osascript -e 'tell application "iTunes" to next track'; break;; "prev" ) echo "Going to previous track."; osascript -e 'tell application "iTunes" to previous track'; break;; "band" ) echo "Playing band $2."; osascript ~/bin/band.scpt $2; break;; "mute" ) echo "Muting iTunes volume level."; osascript -e 'tell application "iTunes" to set mute to true'; break;; "unmute" ) echo "Unmuting iTunes volume level."; osascript -e 'tell application "iTunes" to set mute to false'; break;; "vol" ) echo "Changing iTunes volume level."; vol=`osascript -e 'tell application "iTunes" to sound volume as integer'`; if [ $2 = "up" ]; then newvol=$(( vol+10 )); fi if [ $2 = "down" ]; then newvol=$(( vol-10 )); fi if [ $2 -gt 0 ]; then newvol=$2; fi osascript -e "tell application \"iTunes\" to set sound volume to $newvol"; break;; "stop" ) echo "Stopping iTunes."; osascript -e 'tell application "iTunes" to stop'; break;; "quit" ) echo "Quitting iTunes."; osascript -e 'tell application "iTunes" to quit'; exit 1;; "help" | * ) echo "help:"; showHelp; break;; esac done This new file assumes your iTunes script is "~/bin/band.scpt" Link to comment Share on other sites More sharing options...
Shadrack Posted December 15, 2005 Author Share Posted December 15, 2005 thats a long one. I have most of my iTunes controls globally hotkeyed so I dunno. Although i was wondering if there was a way to get output from an AppleScript command to my shell script and you have a good example in there. thx. Link to comment Share on other sites More sharing options...
Syphonic Posted December 16, 2005 Share Posted December 16, 2005 (edited) What I'd love to know is if there's any way to keep a Terminal window pinned to the desktop. Edited December 16, 2005 by Syphonic Link to comment Share on other sites More sharing options...
crazzy88ss Posted December 16, 2005 Share Posted December 16, 2005 Now I can type: $ photoshop neat_graphic.jpg and Adobe Photoshop will open with the neat_graphic.jpg. If it is already open, then it is brought to the front. why not just click the PS icon on the doc...? Link to comment Share on other sites More sharing options...
Shadrack Posted December 16, 2005 Author Share Posted December 16, 2005 (edited) why not just click the PS icon on the doc...? Edit: I think I can answer your question more quickly. If I just want Photoshop open, yeah clicking on the dock or looking it up through spotlight is a hell of a lot faster then opening a terminal. If I need to open a file, in most circumstance I can get to that file faster through the Terminal then Finder. A few keystrokes combined with <tab> and I'm there. ------original post----- I do that when it is more convenient to do. But whenever I'm working on, say a web page, I find myself more comfortable jumping around directories in a shell environment then I do in any GUI. I know all the commands to do stuff like set permissions and open a file in a particular application. Like I said, the shell isn't for everyone. But I would argue that someone who is proficient at using a shell could do a list of normally "Finder" intensive tasks (creating directories, compressing files, opening this file in that program, creating a new file with this extension, make this file executable by anyone and this other file read only...make these files with this particular regular expression pattern have these permissions...etc..etc...etc). You also game the benefits of being more capable of remote controlling your Mac from across the internet through SSH, which will be faster and more convenient then a VNC session. Also, you can write shell scripts that automate processes a lot easier then you can write UI scripts to automate mouse movement or something. But sitting down and learning such things is probably not worth your time. It all depends on what you do with your computer I suppose. Not for everyone, but I thought I would share what I've found works well for me coming from a Linux environment. Edit: Just for clarification: I love Finder an think it is a wonderful tool. I use it all the time, and I'm not all die hard shell or nothing. Depends on what I am doing. Edited December 16, 2005 by Shadrack Link to comment Share on other sites More sharing options...
Miran Posted December 16, 2005 Share Posted December 16, 2005 Edit: I think I can answer your question more quickly. If I just want Photoshop open, yeah clicking on the dock or looking it up through spotlight is a hell of a lot faster then opening a terminal. If I need to open a file, in most circumstance I can get to that file faster through the Terminal then Finder. A few keystrokes combined with <tab> and I'm there. ------original post----- I do that when it is more convenient to do. But whenever I'm working on, say a web page, I find myself more comfortable jumping around directories in a shell environment then I do in any GUI. I know all the commands to do stuff like set permissions and open a file in a particular application. Like I said, the shell isn't for everyone. But I would argue that someone who is proficient at using a shell could do a list of normally "Finder" intensive tasks (creating directories, compressing files, opening this file in that program, creating a new file with this extension, make this file executable by anyone and this other file read only...make these files with this particular regular expression pattern have these permissions...etc..etc...etc). You also game the benefits of being more capable of remote controlling your Mac from across the internet through SSH, which will be faster and more convenient then a VNC session. Also, you can write shell scripts that automate processes a lot easier then you can write UI scripts to automate mouse movement or something. But sitting down and learning such things is probably not worth your time. It all depends on what you do with your computer I suppose. Not for everyone, but I thought I would share what I've found works well for me coming from a Linux environment. Edit: Just for clarification: I love Finder an think it is a wonderful tool. I use it all the time, and I'm not all die hard shell or nothing. Depends on what I am doing. That's what spotlight is for. Command-space, <type name of file>, click file. Assuming it opens by default in photoshop of course. Link to comment Share on other sites More sharing options...
Shadrack Posted December 16, 2005 Author Share Posted December 16, 2005 That's what spotlight is for. Command-space, <type name of file>, click file. Assuming it opens by default in photoshop of course. doesn't work very well for all the files named "background.png" i have in various folders :p. Link to comment Share on other sites More sharing options...
Syphonic Posted December 16, 2005 Share Posted December 16, 2005 Thanks for the alarm clock script. Worked really nicely with 'Right Here Right Now' by Fatboy Slim. Link to comment Share on other sites More sharing options...
Recommended Posts