Hi,
I have a Tcl script that has a GUI front-end. It also has a non-
interactive mode (by running with a "-nogui" flag).
If -nogui is present, then the script does [wm withdraw .] very early in startup so the GUI is never displayed.
I would now like to run non-interactively as a cron job. In this case,
the system displays the error
no display name and no $DISPLAY environment variable
I've tried to execute
DISPLAY=localhost:0.0 wish9.0 &
interactively but it complains that it can't connect to localhost:0.0.
Same with localhost:1.0.
How do I work around this?
For information, I'm running on Linux Mint 22.3. The script does some
web scraping and runs chrome in a subprocess, so I guess I'm going to
need a DISPLAY at some point.
Many thanks,
Alan
This is probably not going to work.
What you need to do is structure your program something like this:
#!/usr/bin/tclsh
# note: tclsh, not wish above!
if [is_GUI_interactive] {
package require Tk
# build the GUI here...
} else {
# non-interactive (no GUI) code here
}
The "package require Tk" will cause a "fatal" error if the DISPLAY envireonment variable is not defined -- the program will "crash" with an error.
Unless and until "package require Tk happens, the program will be well behaved
in cron's environment.
The wish executable does an effective "package require Tk" as the first step of its main() function -- the wish ececutable is directly linked to libtk.so and its init code (its "main()") does the rest of what package require Tk does -- create the "." toplevel, etc. Doing a withdraw of . is already too late. The call the opens the X11 display has already crashed as DISPLAY is not
defined (and it is not in the cron environment).
Yes, it is perfectly possible to create a script that is both CLI safe and also has a GUI interface.
Have a look at https://github.com/RobertPHeller/ModelRRSystem/blob/master/trunk/Scripts/LCC/OpenLCB_Logic.tcl
for an example of this. This is a program that is both meant to run as a daemon (with no interaction) and with a GUI for interactive configuration purposes.
At Mon, 3 Aug 2026 12:37:55 +0100 Alan Grunwald <nospam.nurdglaw@gmail.com> wrote:
Hi,
I have a Tcl script that has a GUI front-end. It also has a non-
interactive mode (by running with a "-nogui" flag).
If -nogui is present, then the script does [wm withdraw .] very early in
startup so the GUI is never displayed.
I would now like to run non-interactively as a cron job. In this case,
the system displays the error
no display name and no $DISPLAY environment variable
I've tried to execute
DISPLAY=calhost:0.0 wish9.0 &
interactively but it complains that it can't connect to localhost:0.0.
Same with localhost:1.0.
How do I work around this?
For information, I'm running on Linux Mint 22.3. The script does some
web scraping and runs chrome in a subprocess, so I guess I'm going to
need a DISPLAY at some point.
Many thanks,
Alan
On 03/08/2026 14:02, Robert Heller wrote:This is almost always a mistake for any package where a non-GUI useage might make sense. A "package require Tk" should always be put off and conditionally invoked. Or else the package can be said to be a "GUI always" package. If
This is probably not going to work.
What you need to do is structure your program something like this:
#!/usr/bin/tclsh
# note: tclsh, not wish above!
if [is_GUI_interactive] {
package require Tk
# build the GUI here...
} else {
# non-interactive (no GUI) code here
}
The "package require Tk" will cause a "fatal" error if the DISPLAY envireonment variable is not defined -- the program will "crash" with an error.
Unless and until "package require Tk happens, the program will be well behaved
in cron's environment.
The wish executable does an effective "package require Tk" as the first step
of its main() function -- the wish ececutable is directly linked to libtk.so
and its init code (its "main()") does the rest of what package require Tk does -- create the "." toplevel, etc. Doing a withdraw of . is already too late. The call the opens the X11 display has already crashed as DISPLAY is not
defined (and it is not in the cron environment).
Yes, it is perfectly possible to create a script that is both CLI safe and also has a GUI interface.
Have a look at https://github.com/RobertPHeller/ModelRRSystem/blob/master/trunk/Scripts/LCC/OpenLCB_Logic.tcl
for an example of this. This is a program that is both meant to run as a daemon (with no interaction) and with a GUI for interactive configuration purposes.
At Mon, 3 Aug 2026 12:37:55 +0100 Alan Grunwald <nospam.nurdglaw@gmail.com> wrote:
Hi,
I have a Tcl script that has a GUI front-end. It also has a non-
interactive mode (by running with a "-nogui" flag).
If -nogui is present, then the script does [wm withdraw .] very early in >> startup so the GUI is never displayed.
I would now like to run non-interactively as a cron job. In this case,
the system displays the error
no display name and no $DISPLAY environment variable
I've tried to execute
DISPLAY=calhost:0.0 wish9.0 &
interactively but it complains that it can't connect to localhost:0.0.
Same with localhost:1.0.
How do I work around this?
For information, I'm running on Linux Mint 22.3. The script does some
web scraping and runs chrome in a subprocess, so I guess I'm going to
need a DISPLAY at some point.
Many thanks,
Alan
Thanks Robert,
The plot, I regret to say, thickens...
My code is all wrapped into a class, which derives from a homebrew
library class that is itself derived from another homebrew library class.
Say application - library - superlibrary. Both library and superlibrary
are defined within a single package, say libraryPkg
The script currently looks like this:
package require libraryPkg
oo::define application {
.
.
.
}
set app [application new[
if {[lindex argv 0] eq "-nogui"} {
wm withdraw .
$app nogui
exit
}
I don't think it's possible - certainly not trivial - to swap things
around so that Tk is required only after I've detected that -nogui
wasn't specified.
Apologies - I oversimplified slightly in the original message - I
actually run via tclsh, and libraryPkg requires Tk when it, itself is required.
I have a nagging suspicion that I will need to have a display availableThere is a virtual X11 server tool (a X11 server with no actual hardware
when I start chromedriver, or rather when it starts chrome.
If all this is insurmountable, I guess I'll need to go away and rework
the code from scratch :-(
Alan
At Mon, 3 Aug 2026 16:44:24 +0100 Alan Grunwald <nospam.nurdglaw@gmail.com> wrote:
On 03/08/2026 14:02, Robert Heller wrote:
This is probably not going to work.Thanks Robert,
What you need to do is structure your program something like this:
#!/usr/bin/tclsh
# note: tclsh, not wish above!
if [is_GUI_interactive] {
package require Tk
# build the GUI here...
} else {
# non-interactive (no GUI) code here
}
The "package require Tk" will cause a "fatal" error if the DISPLAY
envireonment variable is not defined -- the program will "crash" with an >>> error.
Unless and until "package require Tk happens, the program will be well behaved
in cron's environment.
The wish executable does an effective "package require Tk" as the first step
of its main() function -- the wish ececutable is directly linked to libtk.so
and its init code (its "main()") does the rest of what package require Tk >>> does -- create the "." toplevel, etc. Doing a withdraw of . is already too >>> late. The call the opens the X11 display has already crashed as DISPLAY is not
defined (and it is not in the cron environment).
Yes, it is perfectly possible to create a script that is both CLI safe and >>> also has a GUI interface.
Have a look at
https://github.com/RobertPHeller/ModelRRSystem/blob/master/trunk/Scripts/LCC/OpenLCB_Logic.tcl
for an example of this. This is a program that is both meant to run as a >>> daemon (with no interaction) and with a GUI for interactive configuration >>> purposes.
At Mon, 3 Aug 2026 12:37:55 +0100 Alan Grunwald <nospam.nurdglaw@gmail.com> wrote:
Hi,
I have a Tcl script that has a GUI front-end. It also has a non-
interactive mode (by running with a "-nogui" flag).
If -nogui is present, then the script does [wm withdraw .] very early in >>>> startup so the GUI is never displayed.
I would now like to run non-interactively as a cron job. In this case, >>>> the system displays the error
no display name and no $DISPLAY environment variable
I've tried to execute
DISPLAY|elhost:0.0 wish9.0 &
interactively but it complains that it can't connect to localhost:0.0. >>>> Same with localhost:1.0.
How do I work around this?
For information, I'm running on Linux Mint 22.3. The script does some
web scraping and runs chrome in a subprocess, so I guess I'm going to
need a DISPLAY at some point.
Many thanks,
Alan
The plot, I regret to say, thickens...
My code is all wrapped into a class, which derives from a homebrew
library class that is itself derived from another homebrew library class.
Say application - library - superlibrary. Both library and superlibrary
are defined within a single package, say libraryPkg
The script currently looks like this:
package require libraryPkg
oo::define application {
.
.
.
}
set app [application new[
if {[lindex argv 0] eq "-nogui"} {
wm withdraw .
$app nogui
exit
}
I don't think it's possible - certainly not trivial - to swap things
around so that Tk is required only after I've detected that -nogui
wasn't specified.
Apologies - I oversimplified slightly in the original message - I
actually run via tclsh, and libraryPkg requires Tk when it, itself is
required.
This is almost always a mistake for any package where a non-GUI useage might make sense. A "package require Tk" should always be put off and conditionally
invoked. Or else the package can be said to be a "GUI always" package. If you have control of the package consider breaking it into two packages: one package that contains the pure "computional" code (eg data structure, file-io,
and all of the bits that don't relate to the GUI and than have a separate package that implements the GUI elements (which would likely do a package require on the first package). You really should never have any sort of giant
mega package, but really a number separate smaller packages, each with one self-contained chunk of code -- eg a logical "functional" unit.
I have a nagging suspicion that I will need to have a display available
when I start chromedriver, or rather when it starts chrome.
If all this is insurmountable, I guess I'll need to go away and rework
the code from scratch :-(
There is a virtual X11 server tool (a X11 server with no actual hardware
-- screen, mouse, keyboard), at one point I needed to invesigate that to be able to use libreoffice to convert .docx files to .pdf, becasie libreoffice at
one point wa "agressive" GUI (even with a commandline option "--headless"). I
have since founnd pandoc, a purely command line program thay can (amoungst many other things can convert .docx to .pdf from the command line with out resorting to a GUI). (I complained about libreoffice's "broken" --headless option -- at first the libreoffice devs were hostile to the idea of using libreoffice in a non-GUI envirement, but I believe current versions of libreoffice now behave as I had "expected"...)
Alan
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 74 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 46:35:54 |
| Calls: | 1,100 |
| Files: | 1,339 |
| Messages: | 275,566 |