BASH: How can I successfully pipe prompt strings from built-in programs to custom script functions to then print them on the terminal?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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.
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
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?
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?
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.