How to properly call for "sudo whiptail" inside "while ... done < <( find /sys/... )"?

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Post Reply
appius
Level 1
Level 1
Posts: 2
Joined: Wed Sep 04, 2024 3:19 pm

How to properly call for "sudo whiptail" inside "while ... done < <( find /sys/... )"?

Post by appius »

Hi!

Here is the script:

Code: Select all

#!/bin/bash
set -xu

while read str ; do
    sudo whiptail --yesno "Do it with '$str'?" 8 40
    sudo read -p "Enter additional value to continue: " x
    echo "$str -> $x"
done < <( find /sys/class/block/ )
The script worked in past in Mint 21, but in Mint 22 will not work:
- "whiptail" is broken when used with sudo.
- "sudo read -p ..." is stealing values from "find", do not read from stdin (quite logical, but not very evident).

How to do it properly: read line by line a strings from "find" and same time use other utilities, even with sudo, for data input from other sources?

Default shell/terminal options changed, what a change changed the behavior between releases?
User avatar
txba516
Level 4
Level 4
Posts: 242
Joined: Fri Aug 10, 2007 11:57 am
Location: Atlanta, GA

Re: How to properly call for "sudo whiptail" inside "while ... done < <( find /sys/... )"?

Post by txba516 »

Hi applus,

If I had to guess here, I'd suspect the default handling of input to whiptail and where it goes (stderr vs stdout). You can change the handling in the script. See more info here: https://en.wikibooks.org/wiki/Bash_Shel ... g/Whiptail and here: https://www.redhat.com/sysadmin/use-whiptail.

Cheers!
LM22 x64 Cinnamon & XFCE
Help the forums get answers faster! Mark your fixed problem thread as [SOLVED]
appius
Level 1
Level 1
Posts: 2
Joined: Wed Sep 04, 2024 3:19 pm

Re: How to properly call for "sudo whiptail" inside "while ... done < <( find /sys/... )"?

Post by appius »

It's smth. more fundamental. I guess I'm missing something in Bash. Versions are 5.1.21, 4.3.33. Or I'm missing a thing in understanding of Linux fork().

Are there any specific options or features responsible for stdin/stdout manipulations and pass in the case?

More general example:

Code: Select all

#!/bin/bash
PS4="+:lineno=\$LINENO: "
set -xeu

while read d ; do
    c="$( read -p "Enter smth.: " v ; echo "${v}" )"
    echo "$d -> $c"
done < <( find /sys/class/block/ )
Expected behavior: it requests value for "v" in terminal, and variable "v" value is set by "read" built-in using stdin produced in terminal in child shell instance.

De facto "v" is set in child shell instance from stdout, but from _parent's_ shell stdout, when no explicit redirection. Smth. implicit is going on.

Looks like parent stdout passed into child sub-shell. May be parent and child streams are the same instance of the stream. How to manage it?

Example output:

Code: Select all

+:lineno=9: read d
++:lineno=13: find /sys/class/block/
++:lineno=11: read -p 'Enter smth.: ' var
++:lineno=11: echo /sys/class/block/loop1
+:lineno=11: c=/sys/class/block/loop1
+:lineno=12: echo '/sys/class/block/ -> /sys/class/block/loop1'
/sys/class/block/ -> /sys/class/block/loop1
Are there any specific options or features responsible for stdin/stdout manipulations and pass in the case?
1000
Level 6
Level 6
Posts: 1190
Joined: Wed Jul 29, 2020 2:14 am

Re: How to properly call for "sudo whiptail" inside "while ... done < <( find /sys/... )"?

Post by 1000 »

I don't know sudo well enough.
But if you really need a working script,
you can
- run the whole script with root / sudo privileges
- save variables to a file and then read them back.

You don't need to run with root privileges
- messages
- read command

Example which I used

Code: Select all

#!/bin/bash
set -u

while read str ; do
        echo "str = $str"
    whiptail --yesno "Do it with '$str'?" 8 40
    if [[ $? = 0 ]] ; then
        read -p "Enter additional value to continue: " x
        sudo echo "$str -> $x"
    fi
done < <( find /sys/class/block/ | grep -v loop | grep sda[1234])
Output when clicked: Yes, No , No

Code: Select all

$ bash t2
str = /sys/class/block/sda4
/sys/class/block/sda4 -> /sys/class/block/sda2
str = /sys/class/block/sda3
str = /sys/class/block/sda1
What is the purpose of such a script?
KeithHelms
Level 1
Level 1
Posts: 14
Joined: Wed Nov 22, 2023 11:59 am

Re: How to properly call for "sudo whiptail" inside "while ... done < <( find /sys/... )"?

Post by KeithHelms »

You are trying to use stdin for two different reads at the same time. Use a different file descriptor for the outer read loop

Code: Select all

while read -u 3 d ; do
    c="$( read -p "Enter smth.: " v ; echo "${v}" )"
    echo "$d -> $c"
done 3< <( find /sys/class/block/ )
Post Reply

Return to “Scripts & Bash”