]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
add documentation about usage in command substitutions
authorSzenario Green <greensz@email.de>
Thu, 1 Jan 2026 12:13:37 +0000 (12:13 +0000)
committerMiroslav Lichvar <mlichvar@redhat.com>
Tue, 6 Jan 2026 11:08:13 +0000 (12:08 +0100)
Frequently, the usage of whiptail in command substitutions and in
particular on how the file descriptors need to be redirected to achieve
a user interaction with the submitted output in a bash variable is
explained incorrectly. This can lead to functional breakages of user
code in unexpected ways, for example if stderr is redirected into a file
the script just hangs. This commit introduces documentation for this use
case to the man page.

whiptail.1

index 50d26090b28b892d76974678db2db5d11b7ec8e2..60bb66420e5eac4cbe14a55e2b68f0cbd2bbcc3d 100644 (file)
@@ -284,6 +284,60 @@ to reflect each new percentage.  If stdin is XXX, the first following line is
 a percentage and subsequent lines up to another XXX are used for a new prompt.
 The gauge exits when EOF is reached on stdin.
 
+.SH ON USING USER INPUT
+
+\fBwhiptail\fR writes its user interface components to file descriptor 1 (by
+default \fISTDOUT\fR) and submitted user input (e.g. via input box) to file
+descriptor 2 (by default \fISTDERR\fR). This allows for easy debugging while
+using the command directly.
+
+To further use submitted user input in your scripts there are multiple ways:
+One way is to redirect the captured input to a \fItmp-file\fR or to a
+\fInamed-pipe\fR.
+
+Another way is to use \fBwhiptail\fR in a command substitution \fI$(...)\fR but
+in this case you MUST redirect file descriptor 1 and 2 inside the command
+substitution as follows: File descriptor 1 has to point to an user facing
+terminal, file descriptor 2 has to point to the destination of the submitted
+data. The next example illustrate this followed by an explanation of the code.
+
+.RS
+.nf
+01 |  # Duplicate (make a backup copy of) file descriptor 1
+02 |  # on file descriptor 3
+\fB03\fR |  \fBexec 3>&1\fR
+04 |  
+05 |  COLOR=$(whiptail --inputbox \\
+\fB06\fR |          "What is your favorite color?" 0 60 \fB2>&1 1>&3\fR)
+07 |  
+08 |  # Check if the user pressed OK or Cancel
+09 |  if [ $? = 0 ]; then
+10 |      echo "User selected OK and entered:" "$COLOR"
+11 |  else
+12 |      echo "User selected to cancel."
+13 |  fi
+14 |  
+15 |  # Close file descriptor 3
+16 |  exec 3>&-
+.fi
+.RE
+
+The command substitution in line 05-06 prepares an enviroment for
+\fBwhiptail\fR to run in. In this, file descriptor 1 points to a pipe that will
+eventually be used to fill the variable COLOR; file descriptor 2 points to file
+descriptor 2 of the outer context [i.e. your script] (by default STDERR). Since
+\fBwhiptail\fR outputs the user submitted input to its file descriptor 2, we
+need to set file descriptor 2 to write to the pipe which is initialized on file
+descriptor 1.
+
+But that is not enough: To function \fBwhiptail\fR needs its file descriptor 1
+to point to a terminal so that it can display the inputbox. While it is
+possible to use \fISTDERR\fR passed from the outer context, it is unintuitive
+for UI elements to appear in \fISTDERR\fR since frequently \fISTDERR\fR in the
+outer context is redirected to a file. It is therefore advisable to first make
+a copy of a file descriptor pointing to the user facing terminal (line 03) and
+pointing \fBwhiptail\fRs \fISTDOUT\fR to this file descriptor.
+
 .SH NOTES
 whiptail interprets arguments starting with a dash "\-" as being arguments.
 To avoid this, and start some text in, for example, a menubox item, with a