LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   BASH: How can I successfully pipe prompt strings from built-in programs to custom script functions to then print them on the terminal? (https://www.linuxquestions.org/questions/programming-9/bash-how-can-i-successfully-pipe-prompt-strings-from-built-in-programs-to-custom-script-functions-to-then-print-them-on-the-terminal-4175730963/)

pinqvin 11-17-2023 01:19 PM

BASH: How can I successfully pipe prompt strings from built-in programs to custom script functions to then print them on the terminal?
 
Hi all,

The following piece of code is supposed to pipe messages from built-in programs (like apt) to a couple of custom functions, which should then (i) change the colour of the received messages to make them compliant with my script's colour theme; (ii) append the same messages to a custom log file (irrelevant for now).

The trio (see: my code above) works well up until apt full-upgrade (line 29) should prompt the user with the Do you want to continue? [Y/n] message. But it's not printed on the terminal when piped through my function log_trace(), with the cursor just blinking on an empty line. But it's there, since it prints out as soon as I hit 'n' on the keyboard (to abort apt updates).

I'm sure it's somehow related to one of my custom functions, but cannot figure out the reason. Is it because the "invisible" prompt line doesn't push an EOL signal to bash?

Any help is highly appreciated.

My system: Pop!_OS 22.04 with bash 5.1.16 on top of Linux kernel 6.5.6.

Thank you!
Rustam

smallpond 11-18-2023 06:21 AM

Most output ends with a newline, which is what your read expects when it reads lines of input. The prompt is written without a newline and then apt calls flush to print the buffer anyway. I don't think there is a way to read a variable-length line without a newline because there is no way to know you are at the end. You could read a character at a time using the -n option.

rknichols 11-18-2023 09:49 AM

In the bash built-in "read" function, you could use the "-t timeout" option to accept unterminated lines. You will have to expect repeated timeouts with zero-length reads while no input is available, but always check the return code to detect EOF and break the loop. Since the incomplete line is prompting for user input, a timeout of 1 or 2 seconds should not be noticeable to the user.

grail 11-18-2023 10:38 AM

Not sure if i have missed the point, based on the previous 2 replies, but in answer to this part:
Quote:

The trio (see: my code above) works well up until apt full-upgrade (line 29) should prompt the user with the Do you want to continue? [Y/n] message. But it's not printed on the terminal
Line 29
Code:

apt full-upgrade 2>/dev/null | log_trace "(APT)"
Assuming "apt" is like many other programs, the question is most likely being output to standard error, which you have sent off to /dev/null hell ;)
So it is never being sent to your "log_trace" function

Again, I may have misread, so apologise if I am off base

smallpond 11-19-2023 08:13 AM

I guess I thought prompts should go to stdout and not stderr, but "coding standards" is an oxymoron.

Anyway, if you want to read both streams do "2>&1" instead of "2>/dev/null". There will still be the issue of read expecting a newline.

pinqvin 11-22-2023 02:27 AM

Thank you all for your suggestions! But, unfortunately, none of them works. E.g., read -t command, same as read -n, waits for a user interaction (\n) after a prompt anyway.

I also tried adding one of the IFS delimiters to the end of the string before passing it to read, to no avail.

So is there maybe a command different from read to read prompts (a line at a time) from system commands like apt or find?

Thanks!

grail 11-23-2023 08:25 AM

What happens if you remove the log_trace call?

I would not expect read to work as it is apt (IMHO) that is waiting for input, which you could look at expect to reply or see if this option has a way to bypass any questions?

ntubski 11-24-2023 07:36 AM

Quote:

Originally Posted by grail (Post 6465355)
Assuming "apt" is like many other programs, the question is most likely being output to standard error, which you have sent off to /dev/null hell ;)

OP says the prompt does print after hitting 'n', so it must be going onto stanard output.


Quote:

Originally Posted by pinqvin (Post 6465987)
Thank you all for your suggestions! But, unfortunately, none of them works. E.g., read -t command, same as read -n, waits for a user interaction (\n) after a prompt anyway.

It's possible that the apt program is seeing that its output is not a tty and changes to line buffering, so it is apt itself that is waiting for the \n. Try https://manned.org/unbuffer.1 in addition to read -n or read -t.

I would also point that using read -t in this situation is a bit tricky, as it will timeout and return a non-zero exit code even when it has read partial input. So just while read -t ; ... is not enough.


All times are GMT -5. The time now is 12:17 PM.