terminalstata

Running stata in terminal, how do I get display to display a string in terminal


I am using terminal to run Stata. Is there a way to print or display statements in terminal using Stata?

For example, I may run the following in terminal:

stata-mp -b do test.do

Where test.do contains the following:

display "Hello world"

Ideally, I would like the string to appear in terminal but it doesn't appear within terminal. It is only available in the test.log file that is produced after test.do has finished running.


Solution

  • Stata suppresses all screen output in batch mode, so you are asking for something that's very much at odds with that functionality. Even if you tell Stata to to send commands to your operating system, you won't see their output.

    You can accomplish something like this by executing notifications using a custom program from within Stata. Below is an example for macOS for SMS/text and display notifications using AppleScript. You can extend this to Slack, emails, etc, and to other OSes.

    Here's an example of test.do:

    // This line attempts to display "Hello world", but only visible in the log file
    display "Hello world"
    // This line attempts to run a shell command to echo "Goodbye world", but it
    // does not work in batch mode
    shell echo "Goodbye world" // does not work
    
    
    // Capture and drop any existing program named 'dm' to avoid conflicts
    capture program drop dm
    
    // Define a new program named 'dm'
    program define dm
        // Expect anything as input syntax
        syntax anything
    
        // Remove any double quotes from the input message
        local message = subinstr(`"`anything'"', `"""',"", .)
    
        // Send the message as a text to a specified phone number using AppleScript
        // CHANGE 12048675309 to country code followed by your phone number
        shell osascript -e 'tell application "Messages" to send "`message'" to buddy "12048675309"'
    
        // Display a notification with the message and title "Stata" using AppleScript
        shell osascript -e 'display notification "`message'" with title "Stata"'
    end
    
    // Call the 'dm' program with the message "Step A done"
    dm "Step A done"
    
    // Pause the execution for 5000 milliseconds (5 seconds)
    sleep 5000
    
    // Call the 'dm' program with the message "Step B done"
    dm "Step B done"
    
    dm "All done!"
    

    If you absolutely need to have the status output in terminal, there is a clunky way to get that by setting an environment variable from Stata and checking on it using a shell script that runs the do-file. Below is an example for macOS, stata-mp, and bash.

    1. Example do-file:

    test.do illustrates how to set an OS environment variable to track the execution status of the Stata do file run in batch mode. By setting this variable at different points in the do-file, you can monitor the current status of the execution from outside Stata.

    The code below defines a create_status command inside the do-file to set that environment variable. If you plan to do this a lot, stick this code in your personal ado directory (type personal in Stata to see where that is) and name it create_status.ado.

    capture program drop create_status
    program define create_status
        version 17
        syntax [anything]
    
    
        // Check if the user provided any message, otherwise set to a single empty space
        if missing(`"`anything'"') {
            shell launchctl unsetenv STATA_STATUS
        }
        // Create or modify the environment variable STATA_STATUS
        else {
            local message = subinstr(`"`anything'"', `"""', "", .)
            shell launchctl setenv STATA_STATUS `message'
        }
    end
    
    // (B) Example Usage
    
    // Set the status to empty
    create_status
    
    // Simulate some processing time
    sleep 3000
    
    // Set the status to "running"
    create_status "running"
    
    // Simulate some processing time
    sleep 3000
    
    // Update the status to "completed"
    create_status "completed"
    
    // Simulate some processing time
    sleep 3000
    
    // NB: the last status always needs to be eof to the shell script loop terminates
    create_status "eof"
    

    2. Example Shell Script:

    Name this run_stata.sh and put it in your special scripts directory (or somewhere that is on your PATH). You will need to make the script executable with chmod +x run_stata.sh.

    #!/bin/bash
    # Example: ./run_stata.sh do-file-name.do
    
    # Check if a filename was provided
    if [ -z "$1" ]; then
        echo "Usage: $0 <do-file-name>"
        exit 1
    fi
    
    # Get the filename from the command line argument
    do_file="$1"
    
    # Run the Stata do file in batch mode amd return control to the CLI
    # NB: You may need to change stata-mp to whatever flavor you have running
    stata-mp -b do "$do_file" &
    
    # Initialize a variable to store the previous status
    previous_status=""
    
    while true; do
        # Get the current status
        current_status=$(launchctl getenv STATA_STATUS)
    
        # Check if the status has changed
        if [ "$current_status" != "$previous_status" ]; then
            echo "STATA_STATUS: $current_status"
            previous_status="$current_status"
        fi
    
        # Exit the loop if the status is "eof"
        if [ "$current_status" == "eof" ]; then
            echo "Your do-file $1 has finished running."
            # reset STATA_STATUS
            launchctl unsetenv STATA_STATUS
            break
        fi
    
        # Sleep for 5 seconds before checking again
        sleep 1
    done
    

    You can run it like this from the command line:

    $ run_stata.sh test.do
    STATA_STATUS: running
    STATA_STATUS: completed
    STATA_STATUS: eof
    Your do-file test.do has finished running.