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

Combining command-line and GUI program

58 views
Skip to first unread message

Cecil Westerhof

unread,
Nov 21, 2017, 4:59:05 PM11/21/17
to
At the moment I have the following program to monitor the temperature
of my CPU:
#!/usr/bin/env wish


proc getCPUTemp {} {
if {1 != [regexp -all -line "^CPUTIN: .*$" [exec sensors] answer]} {
error "Did not get a single line from \[exec sensors\] output"
}
return [lindex [regexp -all -inline {\S+} ${answer}] 1]
}

while {1} {
puts [format "%s: %s" [clock format [clock seconds] -format %T] [getCPUTemp]]
after [expr 1000 * (60 - [clock format [clock seconds] -format %S])]
}

I use wish instead of tclsh, because I want to use a parameter to
decide if the command-line is used or TK. (I have to implement the TK
part, but for that I first have to learn it.)

Is this the way to go, or is it possible that wish does not have
implemented certain things?

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

Gerald Lester

unread,
Nov 21, 2017, 5:18:33 PM11/21/17
to
On 11/21/2017 03:52 PM, Cecil Westerhof wrote:
> At the moment I have the following program to monitor the temperature
> of my CPU:
> #!/usr/bin/env wish
>
>
> proc getCPUTemp {} {
> if {1 != [regexp -all -line "^CPUTIN: .*$" [exec sensors] answer]} {
> error "Did not get a single line from \[exec sensors\] output"
> }
> return [lindex [regexp -all -inline {\S+} ${answer}] 1]
> }
>
> while {1} {
> puts [format "%s: %s" [clock format [clock seconds] -format %T] [getCPUTemp]]
> after [expr 1000 * (60 - [clock format [clock seconds] -format %S])]
> }
>
> I use wish instead of tclsh, because I want to use a parameter to
> decide if the command-line is used or TK. (I have to implement the TK
> part, but for that I first have to learn it.)
>
> Is this the way to go, or is it possible that wish does not have
> implemented certain things?

Well, for your goal you should use tclsh instead of wish. Then if your
parameter specifies you want a GUI, do a package require Tk.

Try it interactively.


--
+----------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |
| Email: Gerald...@kng-consulting.net |
+----------------------------------------------------------------------+

Rich

unread,
Nov 21, 2017, 5:51:30 PM11/21/17
to
Cecil Westerhof <Ce...@decebal.nl> wrote:
> At the moment I have the following program to monitor the temperature
> of my CPU:
> #!/usr/bin/env wish
>
>
> proc getCPUTemp {} {
> if {1 != [regexp -all -line "^CPUTIN: .*$" [exec sensors] answer]} {
> error "Did not get a single line from \[exec sensors\] output"
> }
> return [lindex [regexp -all -inline {\S+} ${answer}] 1]
> }
>
> while {1} {
> puts [format "%s: %s" [clock format [clock seconds] -format %T] [getCPUTemp]]
> after [expr 1000 * (60 - [clock format [clock seconds] -format %S])]
> }
>
> I use wish instead of tclsh, because I want to use a parameter to
> decide if the command-line is used or TK. (I have to implement the TK
> part, but for that I first have to learn it.)
>
> Is this the way to go, or is it possible that wish does not have
> implemented certain things?

As Gerald indicated, if you want a combination CLI/GUI from the same
script, using a CLI option to select, then starting from a tclsh is the
way to go.

On modern Tcl's (anything circa about 8.x and above) "wish" is
effectively shorthand for this:

#!/usr/bin/env tclsh
package require Tk

But if you start from a tclsh, your script will start even when no X
server is running (well, no windowing system, but given that MSWin and
MacOS essentially *always* have a windowing system running, the state
of "no windowing system" available at all is typically only seen on
Linux/Unix systems).

Cecil Westerhof

unread,
Nov 21, 2017, 6:28:06 PM11/21/17
to
Not completely true. The script crashes on the:
package require Tk

But when I make that conditional the problem will be solved.

Rich

unread,
Nov 21, 2017, 6:53:14 PM11/21/17
to
If there's no windowing environment, yes, that is the expected outcome.
And, technically, the "script" started in order for the "package
require Tk" to be executed in the first place in order then abort at
that point.

> But when I make that conditional the problem will be solved.

Yep, you'd have a CLI option that "turned on" the "package require Tk"
part per. your request when running the code.

While a single CLI option is easy enough to code, you might consider
the 'cmdline' package in Tcllib for more complicated CLI option
handling.

Robert Heller

unread,
Nov 21, 2017, 8:28:13 PM11/21/17
to
The "package require Tk" will crash (just as wish will crash) is there is "no
windowing system" -- typically on a Linux/Unix system in a non-GUI
environment, like a cron job or slogin without X11 forwarding, etc.

>
> But when I make that conditional the problem will be solved.

Yes, this is what you need to do.

>

--
Robert Heller -- 978-544-6933
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

Robert Heller

unread,
Nov 21, 2017, 8:28:13 PM11/21/17
to
At Tue, 21 Nov 2017 22:52:31 +0100 Cecil Westerhof <Ce...@decebal.nl> wrote:

>
> At the moment I have the following program to monitor the temperature
> of my CPU:
> #!/usr/bin/env wish
>
>
> proc getCPUTemp {} {
> if {1 != [regexp -all -line "^CPUTIN: .*$" [exec sensors] answer]} {
> error "Did not get a single line from \[exec sensors\] output"
> }
> return [lindex [regexp -all -inline {\S+} ${answer}] 1]
> }
>
> while {1} {
> puts [format "%s: %s" [clock format [clock seconds] -format %T] [getCPUTemp]]
> after [expr 1000 * (60 - [clock format [clock seconds] -format %S])]
> }
>
> I use wish instead of tclsh, because I want to use a parameter to
> decide if the command-line is used or TK. (I have to implement the TK
> part, but for that I first have to learn it.)
>
> Is this the way to go, or is it possible that wish does not have
> implemented certain things?

If you want the CLI version to be a *pure* CLI that will work in the absense
of any sort of screen (eg if DISPLAY is not defined), use tclsh, since using
wish for a pure CLI application will not work if there is no display -- it
will just crash. If/when you need the GUI, execute:

package require Tk

This will load in the Tk library and create a main window (.), which you then
populate with your GUI elements.

Something like this:

#!/usr/bin/tclsh

if {$needgui} {
package require Tk
# Build GUI
# Launch GUI...
} else {
# CLI only code

Cecil Westerhof

unread,
Nov 21, 2017, 11:44:06 PM11/21/17
to
Rich <ri...@example.invalid> writes:

> While a single CLI option is easy enough to code, you might consider
> the 'cmdline' package in Tcllib for more complicated CLI option
> handling.

I will look into that. Thanks.

Cecil Westerhof

unread,
Nov 21, 2017, 11:44:06 PM11/21/17
to
When I get the option to start with GUI it would be nice to check for
a windowing system. In this case it is only for Linux, so it is
‘simple’. But for if I make a more complex variant:
- Windows always has a windowing system?
- With unix/linux I only have to check for the DISPLAY environment
variable?

Gerald Lester

unread,
Nov 22, 2017, 1:12:26 AM11/22/17
to
Windows and Mac (OS/x) always have a windowing system.

Checking for the DISPLAY environment variable is likely the correct
answer for a *nix environment.

Christian Gollwitzer

unread,
Nov 22, 2017, 1:21:40 AM11/22/17
to
Am 22.11.17 um 05:35 schrieb Cecil Westerhof:
>> The "package require Tk" will crash (just as wish will crash) is there is "no
>> windowing system" -- typically on a Linux/Unix system in a non-GUI
>> environment, like a cron job or slogin without X11 forwarding, etc.
>
> When I get the option to start with GUI it would be nice to check for
> a windowing system. In this case it is only for Linux, so it is
> ‘simple’. But for if I make a more complex variant:
> - Windows always has a windowing system?
> - With unix/linux I only have to check for the DISPLAY environment
> variable?

So the request is to start the GUI if it is possible, and otherwise
process the CLI? Don't check for yourself. Use error handling:

if {[catch {package require Tk}]} {
# there is no Tk available
} else {
# Tk is loaded
}


Christian

Rich

unread,
Nov 22, 2017, 1:32:09 AM11/22/17
to
Cecil Westerhof <Ce...@decebal.nl> wrote:
> Robert Heller <hel...@deepsoft.com> writes:
>
>> The "package require Tk" will crash (just as wish will crash) is
>> there is "no windowing system" -- typically on a Linux/Unix system
>> in a non-GUI environment, like a cron job or slogin without X11
>> forwarding, etc.
>
> When I get the option to start with GUI it would be nice to check for
> a windowing system. In this case it is only for Linux, so it is
> ?simple?. But for if I make a more complex variant:
> - Windows always has a windowing system?
> - With unix/linux I only have to check for the DISPLAY environment
> variable?

Actually, "package require Tk" does not "crash", it returns an error if
no windowing system is found.

However, if that error is not caught by the script, then the default
error handler aborts the script at the point of the error and prints
out some error info and a stack trace.

So to detect if a windowing system is available, just [catch] the error
from package require Tk and take appropriate action:

if {[catch {package require Tk}]} {
# No windowing system - perform CLI duties
} else {
# Windowing system available - initalize GUI
}

The above should be portable across Linux/Windows/MacOS and likely
the BSD's.

Ralf Fassel

unread,
Nov 22, 2017, 5:20:02 AM11/22/17
to
* Cecil Westerhof <Ce...@decebal.nl>
| When I get the option to start with GUI it would be nice to check for
| a windowing system. In this case it is only for Linux, so it is
| ‘simple’. But for if I make a more complex variant:
--<snip-snip>--
| - With unix/linux I only have to check for the DISPLAY environment
| variable?

Just catch the 'package require' as others have suggested. DISPLAY
might be set but point to a non-existent connection, or you don't have
the correct magic cookie to connect to the X-Server or or or..., in
which cases the 'package require' will fail just as if DISPLAY was not
set at all.

The situation is roughly the same as checking "file readable" and if the
result is true assuming the following 'open' will always succeed...

HTH
R'

Robert Heller

unread,
Nov 22, 2017, 7:44:15 AM11/22/17
to
Yes.

> - With unix/linux I only have to check for the DISPLAY environment
> variable?
>

Yes.

Robert Heller

unread,
Nov 22, 2017, 7:44:15 AM11/22/17
to
*Technically* Mac (OS/x) is a flavor of UNIX and there are possible conditions
where there is no windowing system (or at last not a *MacOSX* windowing
system). If I ssh/slogin to a Mac from a Linux system... Or run a cron job
on a Mac... [Does MS-Winows have anything like cron?] I wonder it is it
possible to boot a Mac in a non-GUI mode... These are probably outlier cases
though from the OP's POV.

>
> Checking for the DISPLAY environment variable is likely the correct
> answer for a *nix environment.
>
>

--

Robert Heller

unread,
Nov 22, 2017, 7:44:15 AM11/22/17
to
Yes. This is probably the best option. All cases are handled in a
cross-platform / all-platform way.

>
>
> Christian
0 new messages