Could not Read from resource, Poll error, while reading device from V4l2src? - device

I have a pipeline,
gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoconvert ! video/x-raw,width=640,height=480 ! xvimagesink
It is working fine, but sometimes if the above pipeline doesn't exited properly, then if i read the device again, then facing below error.
Could not read from resource.. gstv4l2bufferpool.c(1023): gst_v4l2_buffer_pool_poll (): /GstPipeline:Video-Ingestor/GstV4l2Src:CamSource:
poll error 1: Invalid argument (22).
In order to read again, i need to remove the device and reconnect it. Then only i can able to read it.
Is there any other way, such that whenever this error comes, read the device without removing the it?

Related

Conditional actions depending on error output

Is there a way to perform an if statement based on the error output of a command?
For example, I want to use udisksctl in a script which mounts a USB drive and then perform some action on the drive contents.
The drive is not mounted: it should mount it and then perform the
action.
The drive is absent: it should throw an error message and exit;
The drive is already mounted, it should perform the action;
Running udisksctl can have three results in this scenario:
In case 1), it runs successfully.
In the other two cases it returns an error, but:
In case 2), it gives me the error: Error looking up object for device ...
In case 3) it gives me the error: Error mounting /dev/sdb1: GDBus.Error:org.freedesktop.UDisks2.Error.AlreadyMounted: Device /dev/sdb1 is already mounted at
Is there an elegant way to make an if statement which takes different actions based on these two error messages?
Piping the error message to grep like this udisksctl mount -b /dev/disk/by-label/CRUZER 2> >(grep -i "Error looking up object for device") seems to make no difference in the output.
Branching on the text of error messages is brittle; the text could change between versions, or you could get messages which are similar but mean different things, or the output could change to a different language depending on the user's locale. But to do what you are asking, try
if result=$(udiskctl mount -b /dev/disk/by-label/CRUZER 2>&1); then
: success
else
rc=$?
case $result in
*"Error looking up object for device"*)
echo case 2;;
*"Error mounting /dev/sdb"*)
echo case 3;;
*) echo "$0: unexpected error $result" >&2
exit $rc
;;
esac
fi
The case inside the if is a bit unattractive; I suppose you could refactor this to use elif but then you'd have to refactor the capturing of the exit code from the failed command (assuming you care what the exit code was).
You could obviously make the search strings more or less specific; I tried to keep them fairly general.
Thanks to #markp-fuso, this is what I got:
udtmp=$(mktemp /tmp/$(basename "$0".XXXXXXXX))
udisksctl mount -b /dev/disk/by-label/CRUZER 2> $udtmp
if grep -i "Error looking up object for device" $udtmp ; then
exit
elif grep -i "GDBus.Error:org.freedesktop.UDisks2.Error.AlreadyMounted" $udtmp ; then
do something
fi
do something else
#LMC thank you for the heads up. I think I'll be using it anyway because udiskctl works well with Thunar and mnt much less.

Error trapping in SFTP

Im trying to write a unix script that would push file into another server.
I need to know if the file was successfully pushed.
So far what I've found is to write the sftp error into a file.
sftp ${SFTP_USER}#${SFTP_HOST} << ENDP 2> /var/local/err_log.txt
cd ${SFTP_DIR}
put ${OUTPUT_FILE}
bye
ENDP
My assumption is that "2>" would only write the error in the err_log.
So if my err_log is not empty, it means I have encountered an error.
My question is, is this a good approach?
is it correct assumption that only error would be written in the err_log file?
Are there other better ways to do this?
If you want to restrict stderr logging to errors-only, you should use the Quietmode:
-q Quiet mode: disables the progress meter as well as warning and
diagnostic messages from ssh(1).

Correct script construct to monitor RaspPi sound card output and execute CEC command to activate AV receiver?

Apologies in advance - I'm a complete beginner so the code below is probably a car crash but I'd really appreciate any help if anyone can spare a minute?
Aim - I have my RaspPi as a music source to my AV receiver. I've installed libcec onto RPi and the receiver is cec enabled so I am trying to write a script that sends the 'active source' command to the AVR whenever the sound card is active.
The active source command:
echo 'as' | cec-client -d 1 -s
The script to return sound card status:
grep RUNNING /proc/asound/card*/pcm*/sub*/status
I've tried to represent the following logic:
1. If music is playing - send active command (turns on AVR with correct channel) and create the empty file 'yamaha-yes'
2. If yamaha-yes file exists check that music is playing - if not then remove 'yamaha-yes' file.
The idea with the yamaha-yes file is to prevent the script from continually sending the active source command whilst music is playing - it just needs sending once, so I've tried to write it so that the presence of the file whilst music playing leads to no further action.
I was hoping to use the 'watch' command from boot to have this running continually.
#!/bin/bash
musicon="$( grep RUNNING /proc/asound/card*/pcm*/sub*/status )"
file="/etc/yamaha-yes"
if [ -e $file ] ; then
if [ "$musicon" = "" ] ; then
sudo rm /etc/yamaha-yes
fi
else
if [ "$musicon" ] ; then
echo 'as' | cec-client -d 1 -s
sudo touch /etc/yamaha-yes
fi
fi
The current error returned is 'line 8: [: too many arguments'. But I suspect there is a lot more wrong with it than that and was hoping to check I was on the right track before flogging it any further!
Thanks in advance! Tom
EDIT
Some changes made in line with Marc's advice and the code now seems to work - though I realise it still isn't the most elegant read! Perhaps there is a better way of scripting it?
The short answer is that you are missing quotes [ "$musicon" = 'RUNNING' ]. However, there are problems with how your grepping is going to work. When audio is running you could end up with multiple RUNNING values (giving the string RUNNING\nRUNNING or longer) returned which will not equal RUNNING. Also, $musicoff is broken because the ! command doesnt change a commands output, only its return value. "$musicoff" will equal RUNNING only if audio is running, which is the exact opposite of what you want. Fortunately, the fix also simplifies the script.
The behavior of grep is that it returns 0 (true) if it found the search text anywhere, otherwise it returns 1 (false). So, instead of comparing the output of grep against a specific value (which might fail in certain cases) use the return value of grep directly:
musicon="grep RUNNING /proc/asound/card*/pcm*/sub*/status"
if $musicon ; then
echo Music is on;
fi
if ! $musicon; then
echo Music is off;
fi

How should one deal with Mercurial's "nothing changed" error ($? = 1) for scripted commits?

I'm cleaning up a client's tracking system that uses Mercurial (version 2.0.2) to capture state and automatically commits all changes every hour. I migrated it from cron to Rundeck so they will get status if/when things fail, which immediately caused the job to start filling Rundeck's failed jobs due to "nothing changed" errors. I immediately went to Google and I am surprised that this issue is raised, but I did not find answers.*
It seems like three should be a basic, clean sh or bash option (but their command line environment supports Python and pip modules if necessary).
My go-to responses for this type of thing are:
issue the 'correct' command before issuing the command that might fail when things are OK, then failure of the command actually indicates errors
read the docs and use the error codes to distinguish what's happening, implementing responses appropriately**
do some variant of #1 or #2 where I issue the command and grep the output***
* I will concede that I struggle to search for hg material, in part because of the wealth of information, similarity to git, and my bad habit of thinking in git terms. That being said, I see the issue out there, including "[issue2341] hg commit returns error when nothing changed". I did not find any replies to this and I find no related discussion on StackOverflow.
** I see at https://www.selenic.com/mercurial/hg.1.html that hg commit "Returns 0 on success, 1 if nothing changed." Unfortunately, I know there are other ways for commit to fail. Just now, I created a dummy Mercurial (mq) patch and attempted a commit, getting "abort: cannot commit over an applied mq patch". In that instance, the return code was 255.
*** I suppose I can issue the initial commit and capture error code, stdout, and stderr; then process the text if return is 1 and error or continue as appropriate.
If you want a command that only commits when something has changed, write a command that checks if something has changed. You can do it more "elegantly" by writing it as a simple bash conditional:
if [ -n "$(hg status -q)" ]
then
hg commit -m "Automatic commit $(date)"
fi
You can hg status | wc -l (or grep output) before commit, and commit only if there are changes in working directory
My initial workaround (my least favorite of the options I mention) is to add a Rundeck 'error handler', a command that executes in response to an error. My command is:
hg commit -m "Automatic commit..." files 2>&1 | grep "nothing changed" && echo "Ignoring 'nothing changed' error"
This duplicates the 'nothing changed', but suppresses the error only if it is the 'nothing changed' error. Ugly, but tolerable if nobody has better suggestions...

Using inotify-tools and ruby to push uploads to Cloud Files

I wrote a few scripts to monitor an uploads directory for changes, then capture the file uploaded/changed and push it to cloud files using a ruby script. This all works well 95% of the time, the only exception is that occasionally, ruby fails with a 'file does not exist' exception.
I am assuming that the ruby 'push' script is being called before the file is 100% in its new location, so the script is being called a little prematurely.
I tried adding a little function to my script to check if the file exists, if it doesn't, sleep 5 then try again, but this seems to snowball and eventually dies. I then just added a sleep 2 to all calls, but it hasn't helped as I now get the 'file does not exist' error again.
#!/bin/sh
function checkExists {
if [ ! -e "$1" ]
then
sleep 5
checkExists $1
fi
}
inotifywait -mr --timefmt '%d/%m/%y-%H:%M' --format '%T %w %f' -e modify,moved_to,create,delete /home/skylines/html/forums/uploads | while read date dir file; do
cloudpath=${dir:20}${file}
localpath=${dir}${file}
#checkExists $localpath
sleep 2
ruby /home/cbiggins/bin/pushToCloud.rb skylinesaustralia.com $cloudpath $localpath
echo "${date} ruby /home/cbiggins/bin/pushToCloud.rb skylinesaustralia.com $cloudpath $localpath" >> /var/log/pushToCloud.log
done
I am looking for any suggestions to help me make this 100% stable (eventually, I'll serve the uploaded files from Cloud FIles, so I need to make sure its perfect)
Thanks in advance!
EDIT - solved!! - I am watching the 'delete' event... So, this script is firing when local files have been deleted, which dont exist. Derr. :)
Have you made sure it's not something silly as a space in the uploaded file? Try adding quotes around the parameters passed to your script!
Your function calls itself recursively with no exit. Try changing it to use a while loop instead.

Resources