3

Running smbstatus on the command line I get the following:

❯ smbstatus

Samba version 4.17.3 PID Username Group Machine Protocol Version Encryption Signing


Service pid Machine Connected at Encryption Signing

No locked files

However, if I take this same type of command into a script like this:

#!/usr/bin/bash

SMB_STATUS="$(smbstatus)"

echo "Result: $SMB_STATUS"

I get the following:

No locked files
Result:
Samba version 4.17.3
PID     Username     Group        Machine                                   Protocol Version  Encryption           Signing
----------------------------------------------------------------------------------------------------------------------------------------

Service pid Machine Connected at Encryption Signing

I'm actually trying to filter for the "No locked files" line, however I can't seem to do this in a shell script since it seems possibly two processes are being run in the background? I don't know. I'm at a loss how to explain what I'm seeing here.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
KevDog
  • 51
  • so you want the entire output of that command? ok. redirect it to a file, and then echo that output. rm the file after. – j0h Dec 07 '22 at 16:47
  • I can't reproduce this on Debian (using smbstatus version 4.9.5-Debian, though). smbstatus and x=$(smbstatus); echo "$x" return exactly the same thing here. Nothing's written to stderr that might get output first. – Chris Davies Dec 07 '22 at 16:52
  • What does filter for mean to you in I'm actually trying to filter for the "No locked files" line - print that line or delete that line or something else? What do you want SMB_STATUS to contain? – Ed Morton Dec 08 '22 at 01:08

1 Answers1

4

When I see odd behavior like that, one of my first thoughts is that they are separate output streams. You can confirm this by dropping one or the other of stderr and stdout:

smbstatus > /dev/null

and

smbstatus 2> /dev/null

I think you're seeing that difference: smbstatus prints the session IDs ("PID Username Group ...") (source) and connections ("Service pid Machine ...") (source) to stdout while it prints the "locked file" text to stderr (source). The "locked file" text changed from stdout to stderr during this commit on August 8 2022 in samba-4.17.0rc1.

Whether your screen (or shell capturing output via $( ... )) sees stdout first or stderr first is arbitrary unless the sending program flushes the buffer or closes the file handle, which I don't see smbstatus doing.

To filter for the existence of the "No locked files" line, I'd recommend the approaches in How to grep standard error stream (stderr)?:

# in shells that support process substitution such as bash, zsh, or ksh93u+
if smbstatus > /dev/null 2>(grep -qF 'No locked files')
then
   # ...
fi

or

if smbstatus 2>&1 1>/dev/null | grep -qf 'No locked files'
then
   # ...
fi
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • I didn't see the No locked files (or indeed a list of locked files) on stderr. Everything - on 4.9.5-Debian at least - goes through stdout. I wonder if that's an implementation change between that version and the OP's 4.17.3? – Chris Davies Dec 07 '22 at 17:55
  • I think you're right, @roaima -- https://github.com/samba-team/samba/commit/4f21c6fdf90b0af8370fc17b270b5da2a1ff0209 – Jeff Schaller Dec 07 '22 at 18:03
  • 1
    Hmm. I'd say that's a bad commit. If a list of locked files goes to stdout shouldn't the corresponding "No locked files" also go to stdout? However, your solution solves the problem nicely and also explains why I couldn't reproduce it – Chris Davies Dec 07 '22 at 21:38