I'm trying to run a simple code from applescript.
It use blueutil, a command-line utility that can query Bluetooth’s status (on or off) / turn it on / turn it off.
I try this code from rob cottingham:
tell application “Terminal”
do shell script “/usr/local/bin/blueutil status”
set _Result tothe result
if _Result is “Status: on” then
do shell script “/usr/local/bin/blueutil off”
endif
if _Result is “Status: off” then
do shell script “/usr/local/bin/blueutil on”
endif
endtell
Without success.
If i clean all and only keep the lines about turning off or on, it works though.
Cleanest code I seems to get is:
tell application "Terminal"
do shell script "/usr/local/bin/blueutil status"
set theResult to the result
if "result" is "Status: on" then
do shell script "/usr/local/bin/blueutil off"
end if
end tell
But still doesn't work.
Maybe it's about using the result of the query as a variable?
I'm really not a professional it as you probably guessed, so any help will be appreciated !
Thanks,
Christophe.
First of all you don't need Terminal.app at all.
Second of all there is no argument status, to get the power state write:
set powerStatus to do shell script "/usr/local/bin/blueutil -p" as boolean
The result is true or false.
To toggle the power state write:
do shell script "/usr/local/bin/blueutil -p toggle"
To set the power state to on:
do shell script "/usr/local/bin/blueutil -p on"
To set the power state to off:
do shell script "/usr/local/bin/blueutil -p off"
Yes, it's just one line respectively.
And you can get the help message showing the man page.
set helpText to do shell script "/usr/local/bin/blueutil -h"
Related
I was going through a shell script where set -m was used.
My understanding is that set is used to get positional args.
For ex: set "SO community is very helpful". Now, if I do echo $1, I should get SO and so on for $2, $3...
After checking the command with help flag, I got "-m Job control is enabled."
My question is, what is the purpose of set -m in the following code?
set -m
(
current_hash="some_ha54_one"
new_hash=$(cat file.txt)
if [ $current_hash -ne new_hash ]; then
pip install -r requirement.txt
fi
tmp="temp variable"
export tmp
bash some_bash_file.sh &
wait
bash some_other_bash_file.sh &
)
I understand (to the best of my knowledge) what I going on inside () but what is the use of set -m ?
"Job control" enables features like bg and fg; signal-handling and file-descriptor routing changes intended for human operators who might use them to bring background tasks into the foreground to provide them with input; and the ability to refer to background tasks by job number instead of PID. The script segment you showed doesn't use these features, so the set -m call is presumably pointless.
These features are meant for human users, not scripts; and so in scripts they're off by default. In general, code that attempts to use them in scripts is buggy, and should be replaced with code that operates by PID. As an example, code that runs two scripts in parallel with each other, and then collects the exit status of each when they're finished without needing job control follows:
bash some_bash_file & some_pid=$!
bash some_other_file & some_other_pid=$!
wait "$some_pid"; some_rc=$?
wait "$some_other_pid"; some_other_rc=$?
I would like to toggle between Enable/Disable in my applescript command. Can't seem to identify what's wrong with this script. It's not switching its states (toggling) when I run the same command again:
if {"disabled"} contains (do shell script "spctl --status") then
set theAllow to "enable"
else
set theAllow to "disable"
end if
do shell script (("sudo spctl --master-" & theAllow) as string) with administrator privileges
enter image description here
Looking at the source code for spctl, the spctl --status command will either return assessments enabled or assessments disabled. However, if it's disabled, then do shell script "spctl --status" exits with error "assessments disabled" number 1 and you'll need to account for it in some manner.
do shell script "spctl --status"
--> error "assessments disabled" number 1
So, to keep things simple, the following example AppleScript code simply toggles the state of spctl based on it status:
if (do shell script "spctl --status; exit 0") is "assessments disabled" then
do shell script "spctl --master-enable" with administrator privileges
else
do shell script "spctl --master-disable" with administrator privileges
end if
Example output when spctl is disabled while using ; exit 0 to handle error "assessments disabled" number 1:
do shell script "spctl --status; exit 0"
--> "assessments disabled"
do shell script "spctl --master-enable" with administrator privileges
As you can see, by using ; exit 0 after spctl --status, it stops error "assessments disabled" number 1 and allows the script to proceed.
There certainly is more then one way to trap the error, however, this example AppleScript code, that simply toggles the state of spctl, I've shown is simple and straight forward without the need to be more verbose with its error handling.
Otherwise you'll have to code it in a different manner, using a try statement wrapped around the do shell script "spctl --status command and an on error handler.
you could swap the 2 items
if (do shell script "spctl --status") contains "disabled"
assuming the returned string is "assessments disabled", and there's only 1 item to check.
I'm trying to make an Applescript that connects to a list local ssh machines, with each connection opening in a new terminal window. Prior to attempting the ssh connection, I'd like to ping the client to see if it's available: if it is, run the ssh command, if not then iterates to the next client. When I run the script it seems to work for the first connection but then gives me --> error number -10004 for the remaining clients (and hangs the debugger). Any feedback would be greatly appreciated, thanks!
set hosts to {"10.2.0.199", "10.2.0.11", "10.2.0.91", "10.2.1.591", "10.2.0.41"}
set uname to {"asus_client01", "asrock_comp", "msi003", "gigabyte4", "intel05client"}
tell application "Terminal"
activate
repeat with i from 1 to the count of hosts
set this_uname to item i of uname --extract individual username
set this_host to item i of hosts as string --extract iPv4
set uname_host to this_uname & "#" & this_host
set hostUp to true
try
do shell script "ping -c 1 -t 5 " & this_host
on error
set hostUp to false
display dialog this_host & " seems to be down."
delay 2
end try
if hostUp then
do shell script "ssh " & uname_host
end if
end repeat
end tell
There is a difference between do shell script and do script. The difference is that do shell script is part of the standard script addition and will open an non-interactive shell, execute the given string, and return stdout back to you without any help from another application like Terminal. do shell script should never been used in any other tell application block except itself (me) because you violate some AppleScript securities you can find in AppleScript release and technical notes. do script command is part of AppleScript command in the application Terminal. do script will enter the given string in the targeted window and execute that like you have typed in Terminal yourself. do script is only supported by Terminal application and can't be used outside of it.
So it's either do shell script:
do shell script "ping -o stackoverflow.com
or do script by using the Terminal
tell application "Terminal"
do script "ping -o stackoverflow.com"
end tell
So the total script could look something like this:
set hosts to {"10.2.0.199", "10.2.0.11", "10.2.0.91", "10.2.1.591", "10.2.0.41"}
set uname to {"asus_client01", "asrock_comp", "msi003", "gigabyte4", "intel05client"}
--security check: hosts list can't be longer than uname
if (count of hosts) > (count of uname) then return
repeat with i from 1 to count hosts
repeat 1 times -- simulate continue
set currentAddress to item i of hosts
set currentHostname to item i of uname
if not ((do shell script "ping -o -t 5 " & currentAddress & "&>dev/null && echo yes || echo no") as boolean) then
exit repeat -- continue
end if
tell application "Terminal"
do script "ssh " & currentHostname
end tell
end repeat
end repeat
I need to be able to run AppleScript in a shell script. I am using "AppleScript Runner" in order to be in interactive mode, so that dialogs etc. are supported. I've got it working, but I need to get the exit status of the AppleScript Runner app back to the shell, so I can see if there were any errors in the script.
Here is my shell script:
output=$(/usr/bin/osascript << EOT
tell application "AppleScript Runner"
do script "somescript.scpt"
end
EOT)
status=$?
Here my variable $status only ends up with the exit status of the osascript command (which will be 0 whether or not somescript.scpt actually ran successfully), and not the exit status of the app AppleScript Runner.
Does any one know how I might accomplish this?
Thanks!
The -e flag prints errors to stderr and is the default. So you just need to read stderr.
This answer might help you if you aren't familiar with that:
bash variable capture stderr and stdout separately or get exit value
EDIT: Added sample code.
error=`osascript -e 'tell app "Finder" to adtivate' 2>&1`
echo $error
The above on my system captures the error messages.
I have a bash script that performs several file operations. When any user runs this script, it executes successfully and outputs a few lines of text but when I try to cron it there are problems. It seems to run (I see an entry in cron log showing it was kicked off) but nothing happens, it doesn't output anything and doesn't do any of its file operations. It also doesn't appear in the running processes anywhere so it appears to be exiting out immediately.
After some troubleshooting I found that removing "set -e" resolved the issue, it now runs from the system cron without a problem. So it works, but I'd rather have set -e enabled so the script exits if there is an error. Does anyone know why "set -e" is causing my script to exit?
Thanks for the help,
Ryan
With set -e, the script will stop at the first command which gives a non-zero exit status. This does not necessarily mean that you will see an error message.
Here is an example, using the false command which does nothing but exit with an error status.
Without set -e:
$ cat test.sh
#!/bin/sh
false
echo Hello
$ ./test.sh
Hello
$
But the same script with set -e exits without printing anything:
$ cat test2.sh
#!/bin/sh
set -e
false
echo Hello
$ ./test2.sh
$
Based on your observations, it sounds like your script is failing for some reason (presumably related to the different environment, as Jim Lewis suggested) before it generates any output.
To debug, add set -x to the top of the script (as well as set -e) to show commands as they are executed.
When your script runs under cron, the environment variables and path may be set differently than when the script is run directly by a user. Perhaps that's why it behaves differently?
To test this: create a new script that does nothing but printenv and echo $PATH.
Run this script manually, saving the output, then run it as a cron job, saving that output.
Compare the two environments. I am sure you will find differences...an interactive
login shell will have had its environment set up by sourcing a ".login", ".bash_profile",
or similar script (depending on the user's shell). This generally will not happen in a
cron job, which is usually the reason for a cron job behaving differently from running
the same script in a login shell.
To fix this: At the top of the script, either explicitly set the environment variables
and PATH to match the interactive environment, or source the user's ".bash_profile",
".login", or other setup script, depending on which shell they're using.