Skip to content

Conversation

PaulSD
Copy link
Contributor

@PaulSD PaulSD commented Sep 27, 2025

This fixes another potential problem with #169 which #172 failed to fix.

Specifically (as described in #172 comment), log messages and stdout could still get mixed up if one bashio script calls another bashio script as a child (not as a subshell).

Summary by CodeRabbit

  • New Features

    • Logging configuration is now inherited by child processes, ensuring consistent logging across subprocesses and scripts.
  • Bug Fixes

    • Improved logging initialization to avoid unintended redirection in edge cases.
    • Preserves original standard output behavior on an unused descriptor, maintaining previous output handling.
  • Documentation

    • Clarified comments describing logging behavior with subshells and child processes for better maintainability.

Copy link

coderabbitai bot commented Sep 27, 2025

Walkthrough

Updates lib/log.sh to use ${LOG_FD:-} for LOG_FD checks and redirections, exports LOG_FD so child processes inherit it, and updates comments about preserving original stdout and subshell/child behavior. No other files changed.

Changes

Cohort / File(s) Summary
Logging FD handling
lib/log.sh
Use ${LOG_FD:-} for validity checks and redirection, adjust condition/testing to the default-expanded variable, export LOG_FD to the environment for subprocess inheritance, and clarify comments about preserved STDOUT and subshell/child behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Shell as User Shell
  participant Script as lib/log.sh
  participant Env as Environment
  participant Child as Child Process
  participant STDOUT as Original STDOUT (preserved FD)

  Shell->>Script: source / run script
  Script->>Script: evaluate LOG_FD via ${LOG_FD:-}
  Script->>STDOUT: duplicate/preserve original STDOUT on free FD (LOG_FD)
  Script->>Env: export LOG_FD
  Note over Script,Env: LOG_FD exported for inheritance

  Shell->>Child: spawn subprocess
  Child->>Env: inherit LOG_FD
  Child->>STDOUT: write logs via inherited LOG_FD
  Note over Child,STDOUT: logging redirected through preserved FD
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

bugfix

Suggested reviewers

  • frenck

Poem

I hop and tweak a tiny thread,
I tuck stdout where logs are led.
I pass the FD with gentle thump,
So child processes can all jump.
Logs safe and warm — a rabbit's pump. 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely summarizes the primary change by stating that child bashio processes will be able to access the parent LOG_FD variable, directly reflecting the pull request’s main objective of preventing log output and stdout interleaving in subprocesses.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66b6fbc and fb252ac.

📒 Files selected for processing (1)
  • lib/log.sh (1 hunks)
🔇 Additional comments (1)
lib/log.sh (1)

11-18: LOG_FD export covers pre-set non-exported handles.

The conditional still re-validates existing descriptors, and the unconditional export afterward ensures children inherit even already-initialized values. This closes the gap that allowed mixed stdout/logs. Nice work.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9f9ee5 and 66b6fbc.

📒 Files selected for processing (1)
  • lib/log.sh (1 hunks)
🔇 Additional comments (2)
lib/log.sh (2)

11-11: Robust fd validation check — good guard.

Using ${LOG_FD:-} with a writability probe keeps set -u safe and avoids inheriting a stale/closed fd. LGTM.


13-14: Comment clarity improved.

The note now accurately distinguishes subshell vs child process behavior. Thanks.

@agners
Copy link
Contributor

agners commented Sep 29, 2025

Specifically (as described in #172 comment), log messages and stdout could still get mixed up if one bashio script calls another bashio script as a child (not as a subshell).

Can you elaborate what exact real world use-case that fixes? Do you have an example from an add-on where that is actually necessary?

From my testing, the current approach is enough to fix function calling, which from all I know is really used in real world (see #172 (comment)).

Copy link
Collaborator

@sairon sairon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agners while I can't give a real-world example from the wild, I think I get what @PaulSD means. Here's a reproducer:

$ cat test.sh 
#!lib/bashio
echo "PID: $$"
echo "LOG_FD: $LOG_FD"
bashio::log.info "Hello from $$, LOG_FD: $LOG_FD"
./subprocess.sh > test.out

$ cat subprocess.sh 
#!lib/bashio
echo "PID: $$"
echo "LOG_FD: $LOG_FD"
bashio::log.info "Hello from $$, LOG_FD: $LOG_FD"
if bashio::fs.file_exists $0; then
    echo "I exist"
fi
./subprocess2.sh

$ cat subprocess2.sh 
#!lib/bashio
echo "PID: $$"
echo "LOG_FD: $LOG_FD"
bashio::log.info "Hello from $$, LOG_FD: $LOG_FD"

Without the change:

$ LOG_LEVEL=7 ./test.sh 
PID: 79493
LOG_FD: 10
[12:08:38] INFO: Hello from 79493, LOG_FD: 10

$ cat test.out 
PID: 79498
LOG_FD: 11
[12:08:38] INFO: Hello from 79498, LOG_FD: 11
[12:08:38] TRACE: bashio::fs.file_exists: ./subprocess.sh
I exist
PID: 79504
LOG_FD: 12
[12:08:38] INFO: Hello from 79504, LOG_FD: 12

With the change:

$ LOG_LEVEL=7 ./test.sh 
PID: 80223
LOG_FD: 10
[12:09:43] INFO: Hello from 80223, LOG_FD: 10
[12:09:43] INFO: Hello from 80228, LOG_FD: 10
[12:09:43] TRACE: bashio::fs.file_exists: ./subprocess.sh
[12:09:43] INFO: Hello from 80234, LOG_FD: 10

$ cat test.out 
PID: 80228
LOG_FD: 10
I exist
PID: 80234
LOG_FD: 10

IMO the latter is the correct behavior, as there's indeed no mixing of the logging and stdout. Also there's difference in the behavior when the LOG_FD is set for the parent process - as the guard is applied then for all subprocesses and it essentially behaves the same way as the fixed version. While you could argue that you can explicitly export LOG_FD before you call the first bashio script from the main one, I don't think it's really intuitive.

Comment on lines +17 to +18
# Export LOG_FD for use by child bashio processes.
export LOG_FD
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can move this to the conditional block above 🤔

@agners
Copy link
Contributor

agners commented Sep 29, 2025

@agners while I can't give a real-world example from the wild, I think I get what @PaulSD means. Here's a reproducer:

Sure, I understand how it could come to this situation. But do we need to support this case 🤔 🤷 ?

The move to stderr changed the contract of how any bashio script can be used, this is even true with all this changes, e.g. if the stdout of the "root" script is parsed somewhere, that will behave differently as well:

LOG_LEVEL=7 ./test.sh  | grep Hello

I'd make the point why does the root bashio script should be different than subscripts?

IMO the latter is the correct behavior, as there's indeed no mixing of the logging and stdout.

We started off to redirect logging to stdout, since stderr felt wrong. Now we kinda separate it into yet another fd, but only for sub scripts.

IMHO, we made the conscious decision that basio scripts should log to stdout, and we should stick with that. Unfortunately it also broke internal function calling. But that is fixed by #172. But no more magic needed, it's now logging to stdout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants