Using SNAP command - how to force messaging to log file?

If I enter the command

snap list junk

the error message reported is

error: snap "junk" not found

I expect the following to correctly capture any such message in a specified file:

snap list junk 2>&1 >msg_file.txt

That does not work. I’ve tried wrapping the snap command within braces, which I’ve had to do for some cases, but that does not work for this scenario.

Any suggestions?

Test script
#!/bin/sh

tmp="/tmp/$(basename "${0}" ".sh")__$$.tmp" ; rm -f "${tmp}"

#for packageName in junk software-boutique
for packageName in junk
do
	skip=0

	export packageName
	rm -f "${tmp}"
	#snap list "${packageName}" 2>&1 >"${tmp}"
	#{ snap list "${packageName}" 2>&1 } >"${tmp}"
	testor=$( snap list "${packageName}" 2>&1 )

	#testor=$( grep 'error: no matching snaps installed' "${tmp}" )
	#testor=$( grep 'error: snap' "${tmp}" | grep 'not found' )
	#testor=$( grep 'error: snap' "${tmp}" )
	testor=$( echo "${testor}" | grep 'error: snap' )

echo "testor = '$testor'"

	if [ -n "${testor}" ]
	then
		echo "\n No SNAP package by name of '${packageName}' ..."
	else
		if [ -n "${packageName}" ]
		then
			rm -f "${tmp}"
			snap connections "${packageName}" >"${tmp}"

			if [ -s "${tmp}" ]
			then
				echo "\n Found connections related to package '${packageName}':\n"
				cat "${tmp}"
				echo "\n Skip or Continue ? [S/c] => \c" ; read dowhat
				if [ -z "${dowhat}" ] ; then  dowhat="A" ; fi
				case "${dowhat}" in
					[Ss] ) echo "\t Purge of '${packageName}' deferred ...\n" ; skip=1 ;;
					* ) echo " Ignoring status of connections ..." ;;
				esac
			else
				echo " Found no connections related to package.  Proceeding with purge ...\n"
			fi

			if [ ${skip} -eq 0 ]
			then
				echo "to purge"
				#snap remove --purge "${packageName}"
				echo ""
				#snap list "${packagName}"
			fi
		fi
	fi

	echo "\n Hit return to continue with next package ..." ; read k
done
2 Likes

That’s one of bash quirks. You can not redirect after 2>&1. Look,

$ snap list junk
error: no matching snaps installed

$ snap list junk 2>&1 > snap_err.txt
error: no matching snaps installed

#N.B. text remains on screen, not redirected

$ cat snap_err.txt

#N.B. yes, no content, file's empty

$ snap list junk  > snap_err.txt 2>&1

#N.B. no text on screen, it's redirected

$ cat snap_err.txt
error: no matching snaps installed

#N.B. yes, text is redirected into file

$
4 Likes

Weird … because I tried with both /bin/bash and /bin/sh, with both failing the redirect, which I always use for other scripts … without issue !!!

I will reboot into my parallel test environment for 26.04 to see if it is behaving the same way. If behaves as it should, then it is a new issue that crept into /bin/sh at 22.04.5 . :frowning:


Update: Tried the redirects on Xubuntu 26.04 LTS. The issue of the inability by both /bin/bash and /bin/sh being unable to redirect all messages (namely both stdout and stderr to a specified file) is for me a bug. I believe that the bug must reside with SNAP because the behaviour exists for both shells.

I will report to both the Ubuntu forum and the SNAP site (once I have correctly identified the required channel).

Stay tuned …


Edit: Posted as issue on Ubuntu Discourse …

2 Likes

Eugene, I swear that I tried that first without success, which is why I tried other scenarios, again without success. I was pulling my hair out. Today, I try it in the sequence you outlined and now it works!!! I am so … (unspeakable)!

:frowning:

2 Likes

I was in a similar situation few days back. I ended up using | tee. Today I almost typed my reply,

snap list junk | tee junk.log

but stopped to share the output and guess what? It doesn’t work! :rofl:

But everything happens for the good right? I checked online to learn | works by taking output (stdout) of previous command and feeding it to input (stdin) of next. It does not handle stderr by default. We can however use 2>&1 redirection to capture errors as well. So, your command from first post would become,

snap list junk 2>&1 | tee msg_file.txt

If you don’t care about seeing the error message on the terminal, you can simply do,

snap list junk 2> msg_file.txt
5 Likes