Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using python to start programs after logging in

63 views
Skip to first unread message

Cecil Westerhof

unread,
Jan 19, 2017, 2:14:13 PM1/19/17
to
I am writing a python program to start the programs that need to be
started after logging in.

I have the following imports:
from subprocess import check_call, Popen, STDOUT
from time import sleep, strftime

And use the following code:
check_call(tuple('wmctrl -s 10'.split()))
log_file = open('Logging/firefox_%T.log'.replace('%T', strftime('%F_%R')), 'w')
Popen(tuple('firefox'.split()), stdout = log_file, stderr = STDOUT)

The first statement is to go to the correct desktop.

Is this a good way to do things, or could I do it in a better way?

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

John Gordon

unread,
Jan 19, 2017, 2:29:15 PM1/19/17
to
In <878tq6a...@Equus.decebal.nl> Cecil Westerhof <Ce...@decebal.nl> writes:

> I am writing a python program to start the programs that need to be
> started after logging in.

> Is this a good way to do things, or could I do it in a better way?

I think using your window manager's built-in facilities for starting
programs would be better. Why are you using Python instead?

--
John Gordon A is for Amy, who fell down the stairs
gor...@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

MRAB

unread,
Jan 19, 2017, 3:12:47 PM1/19/17
to
On 2017-01-19 19:08, Cecil Westerhof wrote:
> I am writing a python program to start the programs that need to be
> started after logging in.
>
> I have the following imports:
> from subprocess import check_call, Popen, STDOUT
> from time import sleep, strftime
>
> And use the following code:
> check_call(tuple('wmctrl -s 10'.split()))
> log_file = open('Logging/firefox_%T.log'.replace('%T', strftime('%F_%R')), 'w')
> Popen(tuple('firefox'.split()), stdout = log_file, stderr = STDOUT)
>
> The first statement is to go to the correct desktop.
>
> Is this a good way to do things, or could I do it in a better way?
>
Apart from the other answer, your use of .replace is odd. This would be
better:

log_file = open('Logging/firefox_%s.log' % strftime('%F_%R'), 'w')

Even better would be to use the 'with' statement as well.

Cecil Westerhof

unread,
Jan 19, 2017, 4:14:12 PM1/19/17
to
On Thursday 19 Jan 2017 20:29 CET, John Gordon wrote:

> In <878tq6a...@Equus.decebal.nl> Cecil Westerhof
> <Ce...@decebal.nl> writes:
>
>> I am writing a python program to start the programs that need to be
>> started after logging in.
>
>> Is this a good way to do things, or could I do it in a better way?
>
> I think using your window manager's built-in facilities for starting
> programs would be better. Why are you using Python instead?

Because when you use the window managers builtin facilities then all
programs will be started on the same virtual desktop and I want to
start them on different ones.

Second reason is that I want to fetch the programs to start from a
database so I can easily change the programs to be started.

Cecil Westerhof

unread,
Jan 19, 2017, 4:44:24 PM1/19/17
to
The reason is that it is ‘generic’ code. In the future instead of
string it will be a variable and only when the variable contains %T it
should be replaced.


> Even better would be to use the 'with' statement as well.

The same here. Not always has the output to be logged and then I would
use NONE for log_file.

Cecil Westerhof

unread,
Jan 19, 2017, 6:44:11 PM1/19/17
to
I wrote a function for switching to the correct virtual desktop and
starting all the commands. I am also using with now:
def do_desktop(desktop, commands, seconds_to_wait = 10):
desktop_command = ('wmctrl -s ' + desktop).split()
check_call(tuple(desktop_command))
for command_arr in commands:
command = command_arr[0].split()
log_directory = command_arr[1]
directory = command_arr[2]
if (directory != ''):
chdir(directory)
if (log_directory == 'NONE'):
Popen(tuple(command.split()))
else:
log_file_name = log_directory.replace('%T', strftime('%F_%R'))
with open(log_file_name, 'w') as log_file:
Popen(tuple(command), stdout = log_file, stderr = STDOUT)
if (directory != ''):
set_default_dir()
sleep(seconds_to_wait)


The function set_default_dir:
def set_default_dir():
chdir(expanduser('~'))


The example with firefox is then done with:
commands = [
['firefox', 'Logging/firefox_%T.log', ''],
]
do_desktop('10', commands, 30)


Sometimes a command needs to be executed in a different directory,
that is done like:
commands = [
['lein run', 'NONE', 'Clojure/Quotes'],
['xfce4-terminal --maximize --execute screen -S Clojure -c ~/.screenrcClojure', 'NONE', ''],
]
do_desktop('6', commands, 30)

MRAB

unread,
Jan 19, 2017, 7:25:04 PM1/19/17
to
You don't have to pass a tuple to check_call; it'll also accept a list.

> for command_arr in commands:
> command = command_arr[0].split()
> log_directory = command_arr[1]
> directory = command_arr[2]
> if (directory != ''):
> chdir(directory)

There's no need for the parentheses around the 'if' condition.

> if (log_directory == 'NONE'):
> Popen(tuple(command.split()))
> else:
> log_file_name = log_directory.replace('%T', strftime('%F_%R'))
> with open(log_file_name, 'w') as log_file:
> Popen(tuple(command), stdout = log_file, stderr = STDOUT)
> if (directory != ''):
> set_default_dir()

Using 'chdir' is generally a bad idea.

'Popen' will start the process and then continue, so what you're doing
is changing the directory, starting a process, and then changing the
directory again, possibly before the process has truly started (i.e.
you've told the OS to start it, but there might be a small delay before
that happens). Popen accepts a 'cwd' argument, which sets the 'current
working directory' for that process.

> sleep(seconds_to_wait)
>
>
> The function set_default_dir:
> def set_default_dir():
> chdir(expanduser('~'))
>
>
> The example with firefox is then done with:
> commands = [
> ['firefox', 'Logging/firefox_%T.log', ''],
> ]
> do_desktop('10', commands, 30)
>
>
> Sometimes a command needs to be executed in a different directory,
> that is done like:
> commands = [
> ['lein run', 'NONE', 'Clojure/Quotes'],
> ['xfce4-terminal --maximize --execute screen -S Clojure -c ~/.screenrcClojure', 'NONE', ''],
> ]
> do_desktop('6', commands, 30)
>
Why 'NONE'? Why not None?

Cecil Westerhof

unread,
Jan 19, 2017, 11:28:14 PM1/19/17
to
On Friday 20 Jan 2017 01:24 CET, MRAB wrote:

>> I wrote a function for switching to the correct virtual desktop and
>> starting all the commands. I am also using with now:
>> def do_desktop(desktop, commands, seconds_to_wait = 10):
>> desktop_command = ('wmctrl -s ' + desktop).split()
>> check_call(tuple(desktop_command))
>
> You don't have to pass a tuple to check_call; it'll also accept a
> list.

I did not know that. The same for Popen.


>> for command_arr in commands:
>> command = command_arr[0].split()
>> log_directory = command_arr[1]
>> directory = command_arr[2]
>> if (directory != ''):
>> chdir(directory)
>
> There's no need for the parentheses around the 'if' condition.

Thanks, I always thought these were necessary.


>> if (log_directory == 'NONE'):
>> Popen(tuple(command.split()))
>> else:
>> log_file_name = log_directory.replace('%T', strftime('%F_%R'))
>> with open(log_file_name, 'w') as log_file:
>> Popen(tuple(command), stdout = log_file, stderr = STDOUT)
>> if (directory != ''):
>> set_default_dir()
>
> Using 'chdir' is generally a bad idea.
>
> 'Popen' will start the process and then continue, so what you're
> doing is changing the directory, starting a process, and then
> changing the directory again, possibly before the process has truly
> started (i.e. you've told the OS to start it, but there might be a
> small delay before that happens). Popen accepts a 'cwd' argument,
> which sets the 'current working directory' for that process.

I am using cwd now.


>> Sometimes a command needs to be executed in a different directory,
>> that is done like: commands = [ ['lein run', 'NONE',
>> 'Clojure/Quotes'], ['xfce4-terminal --maximize --execute screen -S
>> Clojure -c ~/.screenrcClojure', 'NONE', ''],
>> ]
>> do_desktop('6', commands, 30)
>>
> Why 'NONE'? Why not None?

I am using None now.


Thanks.

Cecil Westerhof

unread,
Jan 19, 2017, 11:59:11 PM1/19/17
to
On Friday 20 Jan 2017 00:36 CET, Cecil Westerhof wrote:

> I wrote a function for switching to the correct virtual desktop and
> starting all the commands. I am also using with now:
> def do_desktop(desktop, commands, seconds_to_wait = 10):
> desktop_command = ('wmctrl -s ' + desktop).split()
> check_call(tuple(desktop_command))
> for command_arr in commands:
> command = command_arr[0].split()
> log_directory = command_arr[1]
> directory = command_arr[2]
> if (directory != ''):
> chdir(directory)
> if (log_directory == 'NONE'):
> Popen(tuple(command.split()))
> else:
> log_file_name = log_directory.replace('%T', strftime('%F_%R'))
> with open(log_file_name, 'w') as log_file:
> Popen(tuple(command), stdout = log_file, stderr = STDOUT)
> if (directory != ''):
> set_default_dir()
> sleep(seconds_to_wait)


I wrote a little better version:
def do_desktop(desktop, commands, seconds_to_wait):
desktop_command = (switch_desktop + desktop).split()
if seconds_to_wait == 0:
seconds_to_wait = 10
check_call(desktop_command)
for command_arr in commands:
command = command_arr[0].split()
log_directory = command_arr[1]
directory = command_arr[2]
if not log_directory:
log_directory = '/dev/null'
log_file_name = log_directory.replace('%T', strftime('%F_%R'))
with open(log_file_name, 'w') as log_file:
Popen(command, stdout = log_file, cwd = directory, stderr = STDOUT)
sleep(seconds_to_wait)

When there is no log_directory I set it to '/dev/null': that makes the
code a little bit cleaner.


And everything is now fetched from the database:
for desktop in cursor.execute(select_desktops).fetchall():
desktop_name = desktop[0]
desktop_value = desktop[1]
desktop_wait = desktop[2]
commands = cursor.execute(select_commands, [desktop_name]).fetchall()
do_desktop(desktop_value, commands, desktop_wait)

John Gordon

unread,
Jan 20, 2017, 12:46:14 PM1/20/17
to
In <878tq6h...@Equus.decebal.nl> Cecil Westerhof <Ce...@decebal.nl> writes:

> > I think using your window manager's built-in facilities for starting
> > programs would be better. Why are you using Python instead?

> Because when you use the window managers builtin facilities then all
> programs will be started on the same virtual desktop and I want to
> start them on different ones.

The window manager doesn't allow you to specify a target desktop? That
seems like a pretty heinous feature omission.

Cecil Westerhof

unread,
Jan 23, 2017, 6:59:10 AM1/23/17
to
On Thursday 19 Jan 2017 20:08 CET, Cecil Westerhof wrote:

> I am writing a python program to start the programs that need to be
> started after logging in.

I published what I have until now at:
https://github.com/CecilWesterhof/PythonScripts/blob/master/startPrograms.py

I do not mind some feedback. ;-)


Next step is to write a GUI program to maintain the database. That is
new territory for me.
0 new messages