AppleScript not working from crontab but it works from terminal - cron

I have the following AppleScript that when we run it on the terminal it works, but when it is triggered by the crontab, it doesn't work.
When it is triggered by crontab, the only step that gets completed is the focus of the app.
tell application "SelfControl" to activate
set myPass to do shell script "security find-generic-password -w -s 'My Test' -a 'account_dummy'"
tell application "System Events"
delay 0.5
tell process "SelfControl"
delay 0.5
tell slider of window "SelfControl" to set value to 1.0
delay 0.5
click button "Start Block" of window "SelfControl"
end tell
delay 0.5
repeat while exists (processes where name is "SecurityAgent")
delay 0.5
tell process "SecurityAgent"
set frontmost to true
if (count of windows) > 0 then
set window_name to name of front window
end if
try
keystroke myPass
delay 0.1
keystroke return
delay 0.1
on error
-- do nothing to skip the error
end try
end tell
delay 0.5
end repeat
end tell
The goal is to schedule the app self-control https://selfcontrolapp.com/
This is how it has been added to the crontab:
*/5 14-23 * * 1,2,3,4,5 osascript /Users/cristobal/Library/Mobile\ Documents/com~apple~ScriptEditor2/Documents/selfcontrol.scpt
Every 5 minutes run is for testing, as the block time is only 1 minute, those values will be updated once I get this working.
Thanks for the help.
Edit for some clarification, I have added some logs and it turns out that the problem is coming from the line where it is getting the password.
This is the error logged:
execution error: security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. (44)

Related

Display a running clock in terminal using bash without using loop

How to display a running clock in a linux terminal without using any for or while loop. Using these loops in scripts with 1 sec duration causes a significant load in the systems.
How about:
watch -n 1 date
Use watch to run a command periodically.
You can make a function which calls itself with a sleep :
#!/bin/bash
function showdate(){
printf '\033[;H' # Move the cursor to the top of the screen
date # Print the date (change with the format you need for the clock)
sleep 1 # Sleep (pause) for 1 second
showdate # Call itself
}
clear # Clear the screen
showdate # Call the function which will display the clock
If you execute this script it will run indefinitely until you hit CTRL-C
If you want to add the date to the terminal window title and your terminal supports it, you can do
#! /bin/bash
while :
do
printf '\033]0;%s\007' "$(date)"
sleep 1
done &
and it won't affect any other terminal output.
This post is ancient, but for anyone still looking for this kind of thing:
#!/bin/bash
printf '\033[;H'
while true; do date; sleep 1; done
This version avoids recursion (and stack faults!) while accomplishing the goal.
(For the record - I do prefer the watch version, but since the OP did not like that solution, I offered an improvement on the other solution.)

Logging sql error from inside shell script

i am trying to implement a error logging mechanism in shell script which will also give me errors inside a sql statement
I am planning to call my script from inside another script and redirecting the error to a logfile..
is there any better option ? please help.
#!/bin/sh
./test.sh 2>&1 >> log_1.log
test.sh contains the follwing code
## testing error logging in sql
result=`sqlplus -s $username/$passwd#$db <<EOF
set serveroutout on
set pagesize 0
set heading off
set echo off
set feedback off
select first_name from employees;
exit;
EOF
if [ $? -ne 0 ]; then
echo "Error exists"
else
echo "$result"
fi
--- Edited after testing the code given by Alex Pool
I did the changes but whenever I am getting an SQL error,log file is not getting generated instead the error is being shown at the command line..
Script name -test_error_log.sh
#!/bin/sh
output=`sqlplus -s -l hr/hr#xe << EOF
whenever sqlerror exit failure rollback
whenever oserror exit failure rollback
set serveroutput on
set heading off
set pagesize 0
set echo off
select **e.firs_name --- wrong field name**
,d.department_name from
employees e , departments d
where e.department_id=d.department_id ;
exit;
EOF`
echo $output
I am calling it from caller_shell.sh in the following way
script name : caller_shell.sh
#!/bin/sh
./test_error_log.sh 2>&1 log_file
When I execute ./caller_shell.sh from command line I am getting the error a
but not at the log_file but at the screen
ERROR at line 1: ORA-00904: "E"."FIRS_NAME": invalid identifier
Please let me know how to resolve this ..
You can use whenever sqlerror to make SQL*Plus exit with an error code, which the shell script will see as the return code:
result=`sqlplus -l -s $username/$passwd#$db <<EOF
whenever sqlerror exit failure rollback
whenever oserror exit failure rollback
set serveroutput on
set pagesize 0
set heading off
set echo off
set feedback off
select first_name from employees;
exit 0;
EOF`
It will exit when the error is seen, and nothing after the point of failure will be attempted. Using failure makes it a generic failure code, but you can specify a particularly value if you prefer. But be aware of shell limits if you use your own value; in most shells anything above 255 will loop back round to zero, so it's not a good idea to try to exit with the SQL error code for example as you might get a real error that happens to end up as zero after it's been mod'ed. Using rollback means that if a failure occurs partway through a script it will roll back any (uncommitted) changes already made.
This will catch SQL errors and PL/SQL errors (unless those are caught by an exception handler and not re-raised), but won't catch SQL*Plus-specific errors - i.e. those starting SP-, such as from an invalid set command.
I've added a -l flag to the sqlplus command so it only tries to connect once, which is helpful for a non-interactive script - sometimes they can hang waiting for subsequent credentials, depending on the context and what else is in the script. I've also fixed the spelling of serveroutput and added a missing backtick...

Bash output happening after prompt, not before, meaning I have to manually press enter

I am having a problem getting bash to do exactly what I want, it's not a major issue, but annoying.
1.) I have a third party software I run that produces some output as stderr. Some of it is useful, some of it is regularly stuff I don't care about and I don't want this dumped to screen, however I do want the useful parts of the stderr dumped to screen. I figured the best way to achieve this was to pass stderr to a function, then use conditions in that function to either show the stderr or not.
2.) This works fine. However the solution I have implemented dumped out my errors at the right time, but then returns a bash prompt and I want to summarise the status of the errors at the end of the function, but echo-ing here prints the text after the prompt meaning that I have to press enter to get back to a clean prompt. It shall become clear with the example below.
My error stream generator:
./TestErrorStream.sh
#!/bin/bash
echo "test1" >&2
My function to process this:
./Function.sh
#!/bin/bash
function ProcessErrors()
{
while read data;
do
echo Line was:"$data"
done
sleep 5 # This is used simply to simulate the processing work I'm doing on the errors.
echo "Completed"
}
I source the Function.sh file to make ProcessErrors() available, then I run:
2> >(ProcessErrors) ./TestErrorStream.sh
I expect (and want) to get:
user#user-desktop:~/path$ 2> >(ProcessErrors) ./TestErrorStream.sh
Line was:test1
Completed
user#user-desktop:~/path$
However what I really get is:
user#user-desktop:~/path$ 2> >(ProcessErrors) ./TestErrorStream.sh
Line was:test1
user#user-desktop:~/path$ Completed
And no clean prompt. Of course the prompt is there, but "Completed" is being printed after the prompt, I want to printed before, and then a clean prompt to appear.
NOTE: This is a minimum working example, and it's contrived. While other solutions to my error stream problem are welcome I also want to understand how to make bash run this script the way I want it to.
Thanks for your help
Joey
Your problem is that the while loop stay stick to stdin until the program exits.
The release of stdin occurs at the end of the "TestErrorStream.sh", so your prompt is almost immediately available compared to what remains to process in the function.
I suggest you wrap the command inside a script so you'll be able to handle the time you want before your prompt is back (I suggest 1sec more than the suspected time needed for the function to process the remaining lines of codes)
I successfully managed to do this like that :
./Functions.sh
#!/bin/bash
function ProcessErrors()
{
while read data;
do
echo Line was:"$data"
done
sleep 5 # simulate required time to process end of function (after TestErrorStream.sh is over and stdin is released)
echo "Completed"
}
./TestErrorStream.sh
#!/bin/bash
echo "first"
echo "firsterr" >&2
sleep 20 # any number here
./WrapTestErrorStream.sh
#!/bin/bash
source ./Functions.sh
2> >(ProcessErrors) ./TestErrorStream.sh
sleep 6 # <= this one is important
With the above you'll get a nice "Completed" before your prompt after 26 seconds of processing. (Works fine with or without the additional "time" command)
user#host:~/path$ time ./WrapTestErrorStream.sh
first
Line was:firsterr
Completed
real 0m26.014s
user 0m0.000s
sys 0m0.000s
user#host:~/path$
Note: the process substitution ">(ProcessErrors)" is a subprocess of the script "./TestErrorStream.sh". So when the script ends, the subprocess is no more tied to it nor to the wrapper. That's why we need that final "sleep 6"
#!/bin/bash
function ProcessErrors {
while read data; do
echo Line was:"$data"
done
sleep 5
echo "Completed"
}
# Open subprocess
exec 60> >(ProcessErrors)
P=$!
# Do the work
2>&60 ./TestErrorStream.sh
# Close connection or else subprocess would keep on reading
exec 60>&-
# Wait for process to exit (wait "$P" doesn't work). There are many ways
# to do this too like checking `/proc`. I prefer the `kill` method as
# it's more explicit. We'd never know if /proc updates itself quickly
# among all systems. And using an external tool is also a big NO.
while kill -s 0 "$P" &>/dev/null; do
sleep 1s
done
Off topic side-note: I'd love to see how posturing bash veterans/authors try to own this. Or perhaps they already did way way back from seeing this.

Redirecting a WSH script without logo

I wrote a jscript script intended to create a CSV file. In theory I should use it like this:
myscript>foo.csv
But the CSV file gets corrupted by "Microsoft (R) Windows Script Host Version 5.8 etc." logo.
I know I can write:
cscript //nologo myscript>foo.csv
but it is a loss of productivity and readability.
Do you have a better solution?
cscript /?
Usage: CScript scriptname.extension [option...] [arguments...]
Options:
//B Batch mode: Suppresses script errors and prompts from displaying
//D Enable Active Debugging
//E:engine Use engine for executing script
//H:CScript Changes the default script host to CScript.exe
//H:WScript Changes the default script host to WScript.exe (default)
//I Interactive mode (default, opposite of //B)
//Job:xxxx Execute a WSF job
//Logo Display logo (default)
//Nologo Prevent logo display: No banner will be shown at execution time
//S Save current command line options for this user
//T:nn Time out in seconds: Maximum time a script is permitted to run
//X Execute script in debugger
//U Use Unicode for redirected I/O from the console
So use
cscript //Nologo //S
Command line options are saved.

How to run script continously in background without using crontab

I have a small script that checks certain condition continously and as soon as that condition is met the program should execute. Can this be done. I thought of using crontab where script runs every 5 min but now I want that to be done without crontab
You probably want to create an infinite loop first, then within that loop you probably want to verify your condition or wait a bit. As you did not mention which scripting language you wanted to use, I'm going to write pseudo code for the example. Give us more info about the scripting language, and perhaps also the conditions.
Example in pseudo code:
# Defining a timeout of 1 sec, so checking the condition every second
timeout = 1
# Running in background infinitely
while true do
# Let's check the condition
if condition then
# I got work to do
...
else
# Let's wait a specified timeout, not to block the system
sleep timeout
endif
endwhile
Example in sh with your input code
#!/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin
# Defining a timeout of 1 hour
timeout=3600
while true
do
case 'df /tmp' in
" "[5-9]?%" ") rm -f /tmp/af.*
;;
*)
sleep $timeout
;;
esac
done
You can then run this script from the shell using 'nohup':
nohup yourscript &

Resources