I want to create an applescript that inserts a separator into the dock. The code for that is:
defaults write com.apple.dock persistent-apps -array-add '{ "tile-type" = "spacer-tile"; }';killall Dock
I figured the easiest way to do it is by doing
do shell script "defaults write com.apple.dock persistent-apps -array-add '{ "tile-type" = "spacer-tile"; }';killall Dock"
but the Script Editor complains:
A identifier can’t go after this “"”.
How do I make a script with brackets within brackets? Better solutions for this problem are also very welcomed.
You have to escape each double quote with a backslash
do shell script "defaults write com.apple.dock persistent-apps -array-add '{ \"tile-type\" = \"spacer-tile\"; }';killall Dock"
Related
AppleScript has no problem dealing with UTF-8 characters inside the script. But it is unable to retrieve UTF-8 characters correctly from the environment variables.
osascript -e 'do shell script "echo " &"你好"'
你好
HELLO=你好 osascript -e 'do shell script "echo "& (system attribute "HELLO")'
你好
Any suggestions to fix this?
Looks like system attribute doesn’t respect the shell environment’s LANG. Eh, they’re both ancient and nasty.
This will give you the right value:
HELLO=你好 osascript -e 'do shell script "echo \"$HELLO\""'
# 你好
Alternatively, use NSUserDefaults via the AppleScript-ObjC bridge. I wrote a bunch of AppleScript libraries a few years back; the File library’s environment variables command uses this approach.
I would like to hide all folders on Desktop. I found the following AppleScript but somehow it doesn't work under el Capitan (I'm running 10.11.5 version) :
try
set toggle to do shell script "defaults read com.apple.finder CreateDesktop"
if toggle = "true" then
do shell script "defaults write com.apple.finder CreateDesktop false"
else if toggle = "false" then
do shell script "defaults write com.apple.finder CreateDesktop true"
end if
end try
do shell script "killall Finder"
delay 0.5
activate application "Finder"
Thanks in advance for help
Your found AppleScript has some issues.
The value of the key CreateDesktop – like the more popular AppleShowAllFiles – is a boolean.
Boolean values of user defaults return "1" or "0" (string) in a do shell script call for a couple of system versions. It's never "true" or "false". To get an usable result you need to coerce it to integer and then to boolean
((do shell script "/usr/bin/defaults read com.apple.finder CreateDesktop") as integer) as boolean
If the key does not exist (the default value is false) catch the thrown error, then toggle the boolean state and write is back with -bool attribute to ensure not to write a string.
After sending killall the Finder relaunches automatically, there's no need to do that in code.
This script can be used also for the AppleShowAllFiles key to show and hide invisible files.
try
set state to ((do shell script "/usr/bin/defaults read com.apple.finder CreateDesktop") as integer) as boolean
on error
set state to false
end try
do shell script "/usr/bin/defaults write com.apple.finder CreateDesktop -bool " & ((not state) as text) & "; killall Finder"
I'm trying to make this script work. It's a Bash script that is meant to take some variables, put them together and use the result to send an AppleScript command. Manually pasting the string echoed from the variable to_osa behind osascript -e to the terminal works as I want and expect it to. But when I try to combine the command osascript -e and the string to_osa, it does not work. How can I make this work?
the_url="\"http://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash\""
the_script='tell application "Safari" to set the URL of the front document to '
delimiter="'"
to_osa=${delimiter}${the_script}${the_url}${delimiter}
echo ${to_osa}
osascript -e ${to_osa}
In addition to working manually the script also works when I write the desired command to a script and then execute it:
echo "osascript -e" $to_osa > ~/Desktop/outputfile.sh
sh ~/Desktop/outputfile.sh
String mashing executable code is error prone and evil, and there's absolutely no need for it here. It's trivial to pass arguments to an AppleScript by defining an explicit 'run' handler:
on run argv -- argv is a list of strings
-- do stuff here
end run
which you then invoke like so:
osascript -e /path/to/script arg1 arg2 ...
BTW, if your script requires a fixed number of args, you also write it like this:
on run {arg1, arg2, ...} -- each arg is a string
-- do stuff here
end run
...
Going further, you can even make the AppleScript directly executable as you would any other shell script. First, add a hashbang as follows:
#!/usr/bin/osascript
on run argv
-- do stuff here
end run
then save it in uncompiled plain text format and run chmod +x /path/to/myscript to make the file executable. You can then execute it from the shell as follows:
/path/to/myscript arg1 arg2 ...
Or, if you don't want to specify the full path every time, put the file in /usr/local/bin or some other directory that's on your shell's PATH:
myscript arg1 arg2 ...
...
So here's how you should be writing your original script:
#!/bin/sh
the_url="http://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash"
osascript -e 'on run {theURL}' -e 'tell application "Safari" to set URL of document 1 to theURL' -e 'end run' $the_url
Quick, simple, and very robust.
--
p.s. If you'd rather open a URL in a new window rather than an existing one, see the manpage for OS X's open tool.
As a general rule, don't put double-quotes in the variable, put them around the variable. In this case it's more complicated, since you have some double-quotes for bash-level quoting, and some for AppleScript-level quoting; in this case, the AppleScript-level quotes go in the variable, the bash-level quotes go around the variable:
the_url="\"http://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash\""
the_script='tell application "Safari" to set the URL of the front document to '
osascript -e "${the_script}${the_url}"
BTW, using echo to check things like this is highly misleading. echo is telling you what's in the variable, not what'll be executed when you reference the variable on a command line. The biggest difference is that echo prints its arguments after they've been through bash parsing (quote and escape removal, etc), but when you say "Manually pasting the string ... works" you're saying it's what you want before parsing. If the quotes are there in the echoed string, that means bash didn't recognize them as quotes and remove them. Compare:
string='"quoted string"'
echo $string # prints the string with double-quotes around it because bash doesnt't recognize them in a variable
echo "quoted string" # prints *without* quotes because bash recognizes and removes them
I'm using AppleScript to launch a quick-and-dirty shell script:
tell application "Terminal"
activate
do script "$(" & quoted form of MyScriptPath & ")"
end tell
Which properly launches a Terminal window and inputs what I would expect:
~$ $('/my script path/myscript.sh')
However, it seems that anything outputted to STDOUT (via echo) is evaluated as if it was inside the $( ) when evaluating/calling the script in the first place:
#!/bin/sh
echo "foobar"
produces:
-bash: foobar: command not found
I've searched far and wide and have not really found a suitable way to escape spaces in the path (rather than using "quoted form of") in AppleScript before sending the script location to Terminal, but I'd much prefer that. I'm using "do script" rather than "do shell script" because the script launching in Terminal is interactive and needs to be focused.
How can I echo to STDOUT when calling the script through $( )?
You don't need $(...) to run a command, only to include the output of that command in another string. You simply need
tell application "Terminal"
activate
do script "/my script path/myscript.sh"
end tell
I have the following script
#!/bin/bash
/usr/bin/osascript << EOT
set myfile to choose file
EOT
no_ext=$(python -c "print '$myfile'.split('.')[0]")
### this works - just need to know how to pass the arg
R CMD Sweave no_ext.Rnw
pdflatex no_ext.tex
open no_ext.pdf
Can anyone point me to "how to pass the variable myfile correctly" ?
EDIT
Thx for all the suggestions!
Don't know what to accept, all of your answers really helped me since I learned a lot from everybody.
The following problems exist in your script:
A variable set in the AppleScript section does become defined in the enclosing shell script. You have to do the data exchange with the shell script by using command substitution.
AppleScripts invoked from a shell script aren't allowed to do user interaction because they do not have an application context. You can use the helper application "AppleScript Runner" to run user interaction commands.
Here is a revised version of your script where those problems are fixed:
#!/bin/bash
myfile=$(/usr/bin/osascript << EOT
tell app "AppleScript Runner"
activate
return posix path of (choose file)
end
EOT)
if [ $? -eq 0 ]
then
echo $myfile
else
echo "User canceled"
fi
First, you need to get the contents of the myfile variable from Applescript to bash. I don't know Applescript, so I'll make a shot in the dark as to how to write to its standard output. Then the python part is just unnecessary complexity (and likely wrong anyway, you were throwing away everything after the first . rather than the last). Next you need a $ before the variable name in bash syntax. I think the following script does what you want:
#!/bin/sh
set -e
myfile=$(osascript <<EOT
set myfile to choose file
write myfile to stdout
EOT
)
no_ext="${myfile%.*}"
R CMD Sweave "$no_ext.Rnw"
pdflatex "$no_ext.tex"
open "$no_ext.pdf"
(set -e at the beginning makes the shell exit immediately if an error occurs, instead of trying to execute pdflatex even though no .tex file has been produced or somesuch.)
Realize that applescript paths are colon ":" delimited. You need slash delimited in bash so in applescript terms that's the "posix path". Also, when using osascript it can't open dialog windows. You must tell an application to open the window. Next, you "return" something from the applescript... that's what goes to bash. Finally, in bash to execute a command and assign the result to a variable use `` around the command. So knowing this here's a shell script to use an applescript to get the myFile variable.
#!/bin/bash
myFile=`/usr/bin/osascript << EOT
tell application "Finder"
activate
set myfile to choose file with prompt "Select the file to use in bash!"
end tell
return (posix path of myfile)
EOT`
echo $myFile