- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 83
 
Open
Description
I have following interactive test script echoStdOutErr.sh
#!/bin/bash
# This is used for testing how scala programs can launch external programs and
# handle / redirect their input and outputs
# Check if the mandatory first argument (exitValue) is provided
if [ -z "$1" ]; then
    echo "Error: exitValue is required as the first argument."
    echo "Usage: "
    echo " "
    echo "$0 exitValue <rowCount>"
    exit 1
fi
# Assign the first argument to exitValue
exitValue=$1
echo "stdOut => Starting: $0 $1 $2 ..."
# Check if rowCount was provided as a command-line argument
if [ -n "$2" ]; then
    rowCount=$2
else
    sleep 1
    # Prompt the user to enter rowCount interactively if not provided
    read -p "Enter the row count: " rowCount
fi
# Print rowCount to stdout
echo "stdOut => Row count entered: $rowCount"
# Print rowCount to stderr
>&2 echo "stdErr => Row count entered: $rowCount"
# Loop from 1 to rowCount
for ((i=1; i<=rowCount; i++))
do
    sleep 1
    # Check if the number is even
    if ((i % 2 == 0))
    then
        # Echo to stdout for even numbers
        echo "stdOut => Even number: $i"
    else
        # Echo to stderr for odd numbers
        >&2 echo "stdErr => Odd number: $i"
    fi
done
sleep 1
echo "stdOut => DONE: $rowCount echoes with exitValue $exitValue"
>&2 echo "stdErr => DONE: $rowCount echoes with exitValue $exitValue"
# Exit with the specified exitValue
exit $exitValue
and test run with input value 4 produces
echoStdOutErr.sh 123
stdOut => Starting: /home/jk/bin/echoStdOutErr.sh 123  ...
Enter the row count: 4
stdOut => Row count entered: 4
stdErr => Row count entered: 4
stdErr => Odd number: 1
stdOut => Even number: 2
stdErr => Odd number: 3
stdOut => Even number: 4
stdOut => DONE: 4 echoes with exitValue 123
stdErr => DONE: 4 echoes with exitValue 123
Here the PROMPT is logged to stderr as you see:
echoStdOutErr.sh 123 > out.log 2> err.log
4
cat err.log
Enter the row count: stdErr => Row count entered: 4
stdErr => Odd number: 1
stdErr => Odd number: 3
stdErr => DONE: 4 echoes with exitValue 123
Problem:
When I launch the script using os.proc(...).spawn(...) and try to log the stdout and stderr, I cannot get the PROMPT part logged anywhere.
Scala-cli test code stdOutErr.scala 
//> using scala 2.13.0
//> using dep com.lihaoyi::os-lib:0.11.4
import java.text.SimpleDateFormat
import java.util.Date
import java.io.{BufferedReader, InputStreamReader, OutputStreamWriter, PrintWriter}
import scala.util.matching.Regex
import scala.util.Try
object StdOutErrEx {
  def main(args: Array[String]): Unit = {
    println(s"Running...")
    val echoCmdSeq: Seq[String] = Seq("echoStdOutErr.sh", "123")
    // Start the subprocess using os.proc with stdout and stderr as pipes
    val process = os.proc(echoCmdSeq).spawn(stdin = os.Pipe, stdout = os.Pipe, stderr = os.Pipe,
      env = Map("TERM" -> "xterm"), mergeErrIntoOut = false, propagateEnv = true)
    // Create BufferedReader for real-time streaming of stdout
    val stdoutReader = new BufferedReader(new InputStreamReader(process.stdout))
    val stderrReader = new BufferedReader(new InputStreamReader(process.stderr))
    val stdinWriter = new PrintWriter(new OutputStreamWriter(process.stdin))
    // Threads to print stdout and stderr in real time
    val stdoutThread = new Thread(() => {
      var line: String = stdoutReader.readLine()
      while (line != null) {
        println(s"STDOUT: $line")
        line = stdoutReader.readLine()
      }
    })
    val stderrThread = new Thread(() => {
      var line: String = stderrReader.readLine()
      while (line != null) {
        System.err.println(s"STDERR: $line")
        line = stderrReader.readLine()
      }
    })
    // Start both threads
    stdoutThread.start()
    stderrThread.start()
    // Write "4" to subprocess stdin
    stdinWriter.println("4")
    stdinWriter.flush()
    // Wait up to millis for the subprocess to terminate, by default waits indefinitely.
    // Returns true if the subprocess has terminated by the time this method returns.
    process.waitFor()
    stdinWriter.close() // Close stdin after writing to indicate EOF
    // Ensure threads finish
    stdoutThread.join()
    stderrThread.join()
    val processExitCode = process.exitCode()
    println(s"Process exited with code: $processExitCode")
  }
}
Running it produces:
scala-cli stdOutErr.scala 
Compiling project (Scala 2.13.0, JVM (17))
Compiled project (Scala 2.13.0, JVM (17))
Running...
STDOUT: stdOut => Starting: echoStdOutErr.sh 123  ...
STDOUT: stdOut => Row count entered: 4
STDERR: stdErr => Row count entered: 4
STDERR: stdErr => Odd number: 1
STDOUT: stdOut => Even number: 2
STDERR: stdErr => Odd number: 3
STDOUT: stdOut => Even number: 4
STDOUT: stdOut => DONE: 4 echoes with exitValue 123
STDERR: stdErr => DONE: 4 echoes with exitValue 123
Process exited with code: 123
scala-cli stdOutErr.scala > out.log 2> err.log
cat err.log 
STDERR: stdErr => Row count entered: 4
STDERR: stdErr => Odd number: 1
STDERR: stdErr => Odd number: 3
STDERR: stdErr => DONE: 4 echoes with exitValue 123
cat out.log
Running...
STDOUT: stdOut => Starting: /home/jk/bin/echoStdOutErr.sh 123  ...
STDOUT: stdOut => Row count entered: 4
STDOUT: stdOut => Even number: 2
STDOUT: stdOut => Even number: 4
STDOUT: stdOut => DONE: 4 echoes with exitValue 123
Process exited with code: 123
As you see PROMPT is not logged.
How can I get the PROMPT logged into stderr? Is this error in os.proc or am I using it incorrectly?
Thank you for your help and support.
Metadata
Metadata
Assignees
Labels
No labels