Hello,
I'm trying to use a python script to set an At job in the shell, and I am wanting to make sure my approach is sound. My understanding is that I need to:
1. Import os to my script and use that to set call the At input buffer.
2. Then, I am thinking I use sys.out to send a formatted string to the buffer, such as 'echo "foo"'.
3. Use sys.out to send ^D to close the buffer.
Is this the correct approach? Many thanks for any advice!
-- Matt
not python, so moved to bar
(Dec-08-2020, 08:50 PM)Larz60+ Wrote: [ -> ]not python, so moved to bar
Not sure why you decided so. Probably you wanted to move the other thread - about JavaScript?
Moved it back to General Coding - it looks like OP wants to work from python script as far as I understand.
You've got a couple of choices here.
The only tricky bit is that you can't give all the info to "at" on its command line, you have to feed it via stdin or from a file. You can give stdin directly from your script via a pipe, or you can do it from an invoked shell.
"at" jobs run on the system, not the shell. The shell is just used for invoking normally at a CLI. You don't need it, and when posssible I avoid interacting with it because it can do powerful things that you're not expecting. But in this case it may be simpler.
Since I don't know of any python modules that directly interface with "at", I'd just use subprocess to run the command, and open a pipe to the subprocess for the necessary commands.
^D is a signal to your keyboard driver that you want to close the file down. In general when you're not using the keyboard, you just close the file. You don't send an explicit EOF. Also, most external communication requires a bytes object, not a str, so it has to be encoded.
Example 1, use a process and a pipe for commands
import subprocess
at_command = "at now + 1 hour".split()
p = subprocess.Popen(at_command, stdin=subprocess.PIPE)
p.communicate("/bin/ls > /tmp/foo\n/bin/ls /tmp/ > /tmp/bar\n".encode())
Example 2, use the shell. Note since the shell is doing all the work here, we pass the shell a string and it parses out everything.
import subprocess
at_command = "echo '/bin/ls > /tmp/foo' | at now + 1 hour"
p = subprocess.Popen(at_command, shell=True).communicate()
Thanks so much for the help, I will try out the method of letting the shell do all the work. I was thinking I would have to use a heredoc and was trying to figure out the syntax within python.
This is my attempt at using the HEREDOC method:
import os
heredoc = """zulip-send --stream test --subject at_test --'message this is a test'END"""
os.system("at 8:55 <<END%s" % heredoc)
print "test"
The simpler version using the pwd command works fine, but with the above situation, 'at' yells at me about trying to use parameters that don't (for it) exist. Why would it be seeing --stream as a parameter for 'at' rather than as a parameter for 'zulip-send'?
import os
heredoc = """pwdEND"""
os.system("at 8:55 <<END%s" % heredoc)
print "test"
1 there's no newline between END and %s, so your heredoc close becomes ENDzulip-send, not END.
2 there's no newline between the end of the command and the END, so the heredoc close isn't recognized.
3 looks like your quotes are wrong around the --message option.
Apologies for the dumb errors, and thank you very much for the help!