0

I have seen this (and I upvoted it), but it falls a bit short from my needs because:

  • I have to I need to give on-terminal feedback (that is easy, just | tee /dev/tty)
  • I have to get input from users in several ways:
    • read -p 'prompt: ' var
    • select yn in "Yes" "No"; do ...
    • git clone from private repository asking user/pass

How can I do this (especially the select stuff)?

My current test setup (cut down to size) is:

#/bin/bash set -e set -x { if lxc list | grep container then : else lxc launch images:ubuntu/20.04 container echo 'waiting for networking to be up-and-running...' | tee /dev/tty sleep 5 echo 'installing base system...' | tee /dev/tty lxc exec container -- apt update lxc exec container -- apt install -y git echo "install documentation processor? " | tee /dev/tty select yn in "Yes" "No" do if [ $yn == "Yes" ] then echo 'installing documentation processor...' | tee /dev/tty lxc exec container -- apt install -y wget lxc exec container -- wget https://github.com/plantuml/plantuml/releases/download/v1.2022.12/plantuml-1.2022.12.jar -O /usr/local/bin/plantuml.jar fi break done read -p 'enter your EMAIL address: ' email | tee /dev/tty lxc exec container --user 1000 --group 1000 --cwd /home/ubuntu --env HOME=/home/ubuntu -- git config --global user.email "$email" read -p 'enter your FULL NAME: ' name | tee /dev/tty lxc exec container --user 1000 --group 1000 --cwd /home/ubuntu --env HOME=/home/ubuntu -- git config --global user.name "$name" lxc exec container --user 1000 --group 1000 --cwd /home/ubuntu --env HOME=/home/ubuntu -- git config --global credential.helper store echo 'cloning repository...' | tee /dev/tty lxc exec container --user 1000 --group 1000 --cwd /home/ubuntu --env HOME=/home/ubuntu -- git clone [email protected]:gabime/spdlog.git echo "enable audio in container? " | tee /dev/tty select yn in "Yes" "No" do if [ $yn == "Yes" ] then for dev in $(find /dev/snd -type c) do lxc config device add container snd_$(basename $dev) unix-char source=$dev path=$dev gid=1000 lxc exec container -- apt install -y alsa-utils done fi break done fi } >lxd_build.log 2>&1 

This has all said defects:

  1. read -p prompts are not seen on terminal (but are in log file)
  2. select yn in "Yes" "No" prompts are not seen on terminal (but are in log file); this is unsurprising as select doesn't accept redirection.
  3. git clone prompt for user/pass are not seen on terminal.

How can I fix this?

7
  • So how your question is not a duplicate of stackoverflow.com/questions/314675/… ? Commented Nov 13, 2022 at 11:46
  • @KamilCuk: no, that is the base and works well, but I also need to have some direct output to terminal, in specific places, to handle interactivity. Especially problematic is select which does not seem to allow redirection. Commented Nov 13, 2022 at 12:23
  • 1
    Does exec 1> >(tee file.txt) answer your question? unix.stackexchange.com/questions/641042/… . I still do not know, if you know that that is easy, just | tee /dev/tty so why not { ... } | tee file.txt? Commented Nov 13, 2022 at 12:26
  • @KamilCuk: thi does not answer my question because I do not want to see on terminal all programs output, but I do want everything on file and I want to see on terminal what needed for user interaction (obviously); I want to see question raised by echo "do you want to install whatever"; select yn in "Yes" "No"; do ..., but I do not want to see apt install output. OTOH I need to have in log file everything, possibly including user choices. I googled a bit, but all solutions are "all or nothing", with little space for "exceptions". Please notify if you think I should update OP. Commented Nov 13, 2022 at 14:38
  • 1
    I would redesign the script so that the interactive prompting takes place before you redirect everything to a log file. Even better, let the user provide answers on the command line if they already know what they want. Scripts which require interactive I/O are problematic because you can't use them as building blocks for higher-level scripts. Commented Nov 14, 2022 at 5:54

1 Answer 1

1

read -p and select both output their prompts to standard error. Make sure you're capturing the right stream if you want to copy their prompts to both the terminal and a file. For example:

read -p 'enter your EMAIL address: ' email | tee /dev/tty # prompt doesn't get duplicated read -p 'enter your EMAIL address: ' email 2>&1 | tee /dev/tty # prompt does get duplicated ### # Note: These cases might get a bit annoying because the redirection # applies to both the prompt and everything inside the select statement # You may have to do some additional redirection inside the select # statement to make everything work exactly the way you want ### select yn in "Yes" "No" ; do break done | tee /dev/tty # prompt does not get duplicated select yn in "Yes" "No" ; do break done 2>&1 | tee /dev/tty # prompt does get duplicated 

git clone might be more complicated. If it's using something like OpenSSH under the covers to perform ssh operations then it could be writing directly to the TTY so you can't redirect its prompts just by redirecting standard out or standard error. You may have to dive into tools like expect to capture the password prompts and write them somewhere else.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.