Apple script if while issiue - macos

Hey guys my Applescript doesn't do what I expect.
Where is my mistake?
try
set NAS to do shell script "ping -c 1 192.168.222.5"
if NAS contains "100.0% packet loss" then repeat until NAS contains "0% packet loss"
do shell script "python /Users/Selim/Desktop/wol2.0.sh"
set NAS to do shell script "ping -c 1 192.168.222.5"
end repeat
delay 20
tell application "Terminal" to activate
end try
I want ping to my NAS and when I don't get response I want to wake him up, but my script stops after send ping without response.
Any idea what I am doing wrong?
I want to send packets until the NAS wakes up.
I have changed the Code
try
do shell script "ping -c 1 192.168.222.5"
on error
set NAS to "100% packet loss"
repeat while NAS contains "100% packet loss"
do shell script "python /Users/Selim/Desktop/wol2.0.sh"
set NAS to do shell script "ping -c 1 192.168.222.5"
if NAS contains "0% packet loss" then exit repeat
end repeat
say "Server startet, 20 sek"
delay 20
end try
tell application "Terminal" to activate
now i don't know how i get the loop to work with the on error command wich i get from the ping

Even if you have found the solution yourself there is no answer here so I try to complete it here. The string when we lay both strings on top of eachother we'll see "100.0%packet loss". As you can see when looking for "0% packet loss" it always will return true when you're sending just 1 packet. To be better safe than sorry you'd better match the entire line "1 packets transmitted, 1 packets received, 0.0% packet loss". Your first solution would be solved by changing the matches (also you can get rid if the if statement, if ping succeeds the first time the repeat will not run once):
set NAS to do shell script "ping -c 1 192.168.222.5 || true"
repeat until NAS contains "1 packets transmitted, 1 packets received, 0.0% packet loss"
do shell script "python /Users/Selim/Desktop/wol2.0.sh"
set NAS to do shell script "ping -c 1 192.168.222.5 || true"
end repeat
delay 20
tell application "Terminal" to activate
Update: A better version who does not match the printed string from ping but matches the returned number and coerce it into a boolean value.
repeat until ping("192.168.222.5")
do shell script "python /Users/Selim/Desktop/wol2.0.sh"
end repeat
delay 20
tell application "Terminal" to activate
on ping(IPNumber)
return (do shell script "ping -t 1 -c 1 " & IPNumber & " >/dev/null && echo yes || echo no") as boolean
end ping

the working script now:
try
do shell script "ping -c 1 192.168.222.5"
on error
set NAS to "q"
repeat until NAS contains "1 packets transmitted, 1 packets received, 0.0% packet loss"
do shell script "python /Users/Selim/Documents/scripte/wol2.0.sh"
delay 0.1
try
set NAS to do shell script "ping -c 1 192.168.222.5"
end try
end repeat
delay 5
end try
tell application "Kodi" to activate

Related

Terminal exit without performing action

I've made a script which have a block of code launching Terminal to retrieve picture from a server, using FTP.
When I run the script under the script editor, everything is OK: the script launch the Terminal, open the FTP session, set the destination path, get the files, delete them from the server, close connexion, wait the end of Terminal activty and then quit.
But when I run my Script as application, in about 90% of cases, the app launch Terminal and then Terminal quit immediatly. When the Terminal seems to "get" correctly the FTP commands, connexion is done, getting file and so on. Perfectly. But this happens only in a few cases.
Here the last code I have for this part:
tell application "Terminal"
activate
-- Wait for "no more activity"
set frontWindow to window 1
repeat until busy of frontWindow is false
delay 1
end repeat
-- Perform FTP actins
set shell to do script "ftp -i ftp://user_ftp:pass_ftp#host_ftp/" in window 1
do script "lcd ~/Desktop/tmp_instagram/" in shell
do script "mget *.jpg" in shell
do script "mdel *.jpg" in shell
do script "bye" in shell
-- Wait for no more activity
set frontWindow to window 1
repeat until busy of frontWindow is false
delay 1
end repeat
end tell
tell application "Terminal" to quit saving no -- Saving no to avoid conf alert
For avoiding you to loose your time, here are some of the tests I've made, without any success:
Setting the whole FTP command in one line so.
Put a delay 5 after the ativate, rather than the repeat on busy
Put a delay after the ftp command
In fact, the Terminal seems to close before receiving the FTP command (opened and closed immediatly).
Thanks to Mark Setchell comment I tried without using the "shell" command and in fact it seems to be the key. Here is a piece of code which run correctly:
tell application "Terminal"
activate
set w to window frontmost
do script "ftp -i ftp://xxxxx:yy#dddddd/" in w
do script "lcd ~/Desktop/tmp_aarecno_instagram/" in w
do script "mget *.jpg" in w
do script "mdel *.jpg" in w
do script "bye" in w
set frontWindow to window 1
repeat until busy of frontWindow is false
delay 1
end repeat
end tell

Improving script efficiency and reliability

I have this sample code which basically repeats ~20k times. The only thing that changes is the id= in the address and in the echo command line. The id= in the address and the id= in the echo line always correspond. I am running this script on a MAC if that is of any importance.
I would like to improve this script if possible to make it more reliable. Sometimes I either lose connectivity or the session to the server is closed and I am required to log in again but the script keeps running oblivious of the situation. I would like the script to pause if for some reason that happens.
Also after the open command is called, sometimes the server takes longer to responds but the osascript command forces the tab to close after the sleep 2 command has elapsed. This puts me in a position where I am not sure if the server actually took into account the url. Increasing the sleep time is not very reliable. What could be done on that front?
[...]
open 'https://domaineName.com/admin/?adsess=dhnchf6ghd5shak4Dghtfffvw&app=core&module=members&controller=members&do=spam&id=1&status=1' -g
sleep 2
osascript -e 'tell window 1 of application "Safari"
close (tabs where index < (get index of current tab))
end'
echo "done id=1"
open 'https://domaineName.com/admin/?adsess=dhnchf6ghd5shak4Dghtfffvw&app=core&module=members&controller=members&do=spam&id=5&status=1' -g
sleep 2
osascript -e 'tell window 1 of application "Safari"
close (tabs where index < (get index of current tab))
end'
echo "done id=5"
[...]
Any help would be appreciated.
Thank you
You will have to write a script that checks if the main script (lets say main.sh) is currently running on the server (like ps -ef|grep main.sh|grep -v grep)
Check the above output and then execute main.sh inside this script.
This way there is no need for using delay/sleep commands.

How do I check for internet connection OSX

My iMac wi-fi is a bit unstable. Sometimes it says it's connected and has full signal, but webpages won't load in Safari or Chrome. I have to turn wifi off/on to fix it.
The weird thing is when I ping google.com on Terminal, I have 0% packet loss.
PING www.google.com (68.104.213.123):
56 data bytes 64 bytes from 68.104.213.123: icmp_seq=0 ttl=52 time=21.530 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 21.530/21.530/21.530/0.000 ms
I made this Apple Script to try to fix this, but it seems like I need another method for checking actual internet connection instead of just pinging. What could I do?
repeat
try
do shell script "ping -o -t 2 www.google.com"
on error
say "Couldn't connect"
do shell script "networksetup -setairportpower en1 off"
do shell script "sleep 5"
do shell script "networksetup -setairportpower en1 on"
end try
delay 60
end repeat
curl www.apple.com will access the internet from terminal
Get inspiration from above question and answer, I changed code as below:
on idle
try
do shell script "curl -m 4 www.google.com"
on error
say "Couldn't connect"
do shell script "networksetup -setairportpower en1 off"
do shell script "sleep 5"
do shell script "networksetup -setairportpower en1 on"
end try
return 60
end idle
Because if you use repeat, you cannot exit program. By using on idle, you can easily exit program at any time. But you MUST save the script as runnable and check the keep it running checkbox when saving.

Applescript - How to run a single bash command from terminal and wait for response before continue?

I have a modelinfo.sh file, if I run it in Terminal it echos/saves results to a TXT file.
To execute this file from Terminal I use command:
./modelinfo.sh -s C8QH74G6DP11
With this command it saves results for given serialnumber: C8QH74G6DP11
I need to get reports for 5000 serials, so I think AppleScript might help me?
I have wrote this code with AppleScript:
tell application "Terminal"
do script ("./modelinfo.sh -s C8TJ14JWDP11") in window 1
do script ("./modelinfo.sh -s C8QH74G6DP12") in window 1
do script ("./modelinfo.sh -s C8QKGFWSDP13") in window 1
do script ("./modelinfo.sh -s C8QKFR5FDP14") in window 1
end tell
With this Code above my IP gets Blocked and I get only report for the first serialnumber.
I have also tried:
on delay duration
set endTime to (current date) + duration
repeat while (current date) is less than endTime
tell AppleScript to delay duration
end repeat
end delay
tell application "Terminal"
do script ("./modelinfo.sh -s C8TJ14JWDP11") in window 1
delay 20
do script ("./modelinfo.sh -s C8QH74G6DP12") in window 1
delay 20
do script ("./modelinfo.sh -s C8QKGFWSDP13") in window 1
delay 20
do script ("./modelinfo.sh -s C8QKFR5FDP14") in window 1
end tell
But this code doesn't help either..
Last I tried:
tell application "Terminal"
do script ("./modelinfo.sh -s C8TJ14JWDP11") in window 1
end tell
This last script I can run as many times as I want and I always gets the report without getting my IP blocked.
It looks like Applescript runs all 4 serials at once even I get IP blocked?
Since I am able to run single check multiple times without getting blocked.
Can anyone please help and point me in right direction?
Is it possible to this with Applescript?
Or can I make a new bash file which runs all my 5000 commands 1 by 1?
Thank you
Updated Answer
If you want to count the lines and give an indication of progress, replace the code below with this:
#!/bin/bash
declare -i total
total=$(wc -l <sn.txt) # count the lines in sn.txt
i=1
while read sn; do
echo "Fetching $sn ($i of $total)"
./modelinfo.sh -s "$sn"
((i++))
done < sn.txt
Original Answer
No idea why anyone would use Applescript for this - it is clearly a simple bash script to run from Terminal.
Assume your serial numbers are saved in a file called sn.txt like this:
C8QH74G6DP11
C8TJ14JWDP11
C8QH74G6DP12
C8QKGFWSDP13
You would then save the following in a file called fetch in your HOME directory. It reads your serial numbers one at a time and fetches them.
#!/bin/bash
while read sn; do
echo Fetching $sn...
./modelinfo.sh -s "$sn"
done < sn.txt
Then you would go into Terminal and type the following to make it executable:
chmod +x fetch
and then you can run it by typing
./fetch
You start Terminal by holding down Command and tapping the Spacebar then typing Ter and Spotlight will guess you mean Terminal, then you just hit Enter to actually start it.
Well, here is the common approach in Applescript to use the approach you are trying.
property serialList: {"C8TJ14JWDP11", "C8QH74G6DP12", "C8QKGFWSDP13", "C8QKFR5FDP14"}
tell application "Terminal"
repeat with aSerial in serialList
do script ("./modelinfo.sh -s " & aSerial) in window 1
delay 20
end
This should work. However, the state of the terminal window needs to be finished with the process and ready for the next call for this to work, so a delay of 20 may be too simplistic. Put the above coded inside a try block, to see any error.
try
-- above code goes here
on error err
display dialog err
end try
Another approach however, is to include the shell commands directly in an Applescript without going through the Terminal app, using
do shell script
You'll have to post the contents of your modelinfo.sh file to get a sense of that possibility.

Remotely rebooting multiple Macs at once

We have a network of 9 Macs which I'd like to shut down all at once.
Right now I'm using this AppleScript but as you can see, it uses SSH to shut down the computers one by one. And if one of them is already down, the script will freeze.
Is there any way for me to shut all those Macs at once?
set finalIP to 100
repeat until finalIP is 109
tell application "Terminal"
activate
set success to 0
do script "echo Rebooting.."
do script "ssh -l username 192.168.1." & finalIP in front window
delay 1
repeat until success = 1
if last word of (contents of front window as text) = "no" then
do script "yes" in front window
delay 1
else if last word of (contents of front window as text) = "password" then
do script "password" in front window
set success to 1
do script "echo About to reboot.." in front window
else
delay 1
end if
end repeat
do script "sudo reboot" in front window
repeat until last word of (contents of front window as text) = "password"
delay 1
end repeat
do script "password" in front window
close front window
end tell
set finalIP to finalIP + 1
delay 1
end repeat
tell application "Terminal" to quit
You could simply set a timeout to the ssh connect:
ssh -o ConnectTimeout=10 -l ...
(This is a 10 second timeout, adjust to fit your need.)
Also really think about using keys for your connections. There is really no good reason to put SSH passwords in a script. (And if you do that, add the -o BatchMode=yes option too - it will skip hosts you can't log into with your key.)
The -o flag lets you specify a time out, so that when it doesn't succeed in connecting after the specified amount of seconds, it aborts.
imac$ ssh -o ConnectTimeout=5 123.45.6.7
ssh: connect to host 123.45.6.7 port 22: Operation timed out

Resources