0

Hope someone out there with knowledge on Tcl, Expect and Bash able to guide me for following below:

I am trying to print out user inputs on each line using a for loop and array till EOF (end of file) using the CTRL-D keyboard shortcut. However, the result is not as expected, I am unsure what the syntax for line 22 should be as the array index seem to not register variable i

puts "User: ${inputs_array[$i]}"

print_inputs.sh

#!/bin/bash

# While Loop to get user inputs
echo '======For User Inputs======'
while read line
do
  if [ "${line}" == '' ]
  then
    continue
  else
    inputs_array=("${inputs_array[@]}" "$line")
  fi
done


# Prints out using Tcl script
echo '======Prints out======'
{
    /usr/bin/expect << EOF

    for {set i 0} {\$i < ${#inputs_array[@]}} {incr i} {
        puts "User: ${inputs_array[$i]}"
    }

EOF
}

Result:

======For User Inputs======
Sad
Happy
======Prints out======
User: Sad
User: Sad

Below is the bash and Tcl version I am currently using:

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
% puts $tcl_version
8.5

Thanks in advance!

2
  • 2
    It seems like it might be simpler to move the reading of the lines into the expect script. Tcl's pretty good at that. But you'll probably want to make the expect script be primarily expect, not bash; mixing languages is just a recipe for annoyance and quoting fights. Commented Jan 5, 2022 at 17:03
  • Pardon my poor scripting skill and thank you for the advice @DonalFellows Actually, the reason I am writing an expect script inside a bash script because of my lack of knowledge in getting user's password input using an expect script. I've spend a few days searching and reading the man page on expect, but unable to find a way to do so. Commented Jan 6, 2022 at 8:12

1 Answer 1

1

Consider Donal's advice: this doesn't need to be a mixed-language program. However:

First, use bash's readarray command that reads lines of input into an array: replace the bash while loop with this one command:

readarray -t inputs_array

A caveat: this does not filter out the empty lines as you do in the array.

Next, expect cannot access shell variables. You need to share variables through the environment. However, environment variables cannot be arrays. I'd suggest this:

export array_contents
array_contents=$(printf '%s\n' "${inputs_array[@]}")

# Prints out using Tcl script
echo '======Prints out======'

# Note the heredoc word is quoted.
/usr/bin/expect << 'EOF'

    set inputs [split $env(array_contents) \n]
    foreach input $inputs {
        puts "User: $input"
    }

EOF

With these changes, the output would look like

$ bash print_inputs.sh
======For User Inputs======
foo
bar
baz
======Prints out======
User: foo
User: bar
User: baz

Or, with programmatic input

$ { echo foo; echo bar; echo baz; } | bash print_inputs.sh
======For User Inputs======
======Prints out======
User: foo
User: bar
User: baz
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.