You are not logged in.
I'm still wondering what can cause a script to stop working after some time? Like you said ToZ, a script should run from start to end, forever.
Best guess is that something fails along the way here.
inotifywait -q -m -r -e delete $DIR | while read D E F; do
play /home/shamu/My-sounds/trash-empty.wav
notify-send -i user-trash "Trash" "emtpy-trash sound should play"
done
Try with
while : ; do
inotifywait -q -m -r -e delete $DIR | read
play /home/shamu/My-sounds/trash-empty.wav
notify-send -i user-trash "Trash" "emtpy-trash sound should play"
sleep 2
done
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
Thanks Misko_2083, If it stops again, I will try that! But I don't think it's the script because if it was, it would never work. But it does, for 30-40 minutes. After that the damn thing "goes to sleep" and only a reboot can make it work again.
Linux Mint Xfce 21.1
Offline
Maybe KBar has some ideas, but he's been silent...I guess, this crazy "no sense" trash empty sound project is not his style...
It's nothing like that, not at all. I've just been working on a couple of other shell scripts and this seemed to be one too many. Apologies.
What I usually do to debug my scripts is enable execution tracing and redirect stderr to a temporary file, so:
#!/bin/sh -x
exec 2>$(mktemp)
However, it can get rather big quite fast. Does your main loop run each second? If so, waiting for half an hour shouldn't cause any problem. Just keep an eye on the log file. `tail -f` works, but I usually open it in less, so that I can examine it more closely, and then press Shift+F to emulate `tail -f`.
I'm not familiar with how system sounds work. I'll try to look at it more closely and see if I can offer a solution. Make sure to re-read ToZ's instructions and double check your script for logic errors. While you're at it, run a shellcheck on it. It's available on many distros. `apt install shellcheck` & `shellcheck /path/to/script` should work.
Last edited by KBar (2022-07-11 17:31:18)
Remember to edit the subject of your topic to include the [SOLVED] tag once you're satisfied with the answers or have found a solution (in which case, don't forget to share it as well), so that other members of the community can quickly refer to it and save their time. Pretty please!
Offline
Hi KBar, I knew it! Teasing you a little bit did wake you up...Thanks!
However:
Does your main loop run each second? If so, waiting for half an hour shouldn't cause any problem. Just keep an eye on the log file. `tail -f` works, but I usually open it in less, so that I can examine it more closely, and then press Shift+F to emulate `tail -f`.
Unfortunately, this is all "Chinese" to me...I love Linux but I found it too late, when I was already too old to learn. My brain is not like it used to be...That is why I rely on this great forum and wonderful people. This forum is by far the best, most friendly and helpful among all Linux forums.
I do re-read Toz's instructions. I'm sure the script is correct, otherwise it would not work at all. But something stops it...Anyway, I'm now running two different scripts in two distros, we'll see which one works better...
Sorry about "teasing" just tried to be funny...Thanks for stopping by!
Linux Mint Xfce 21.1
Offline
There's at least half a dozen scripts of all colors and shapes, so to say that I'm confused a bit is not saying much.
What distro are you running? Is it Debian-based (Xubuntu, Debian Xfce, Devuan, and the likes)? If so, can you check whether you have any oom-reaper (out-of-memory killer, that runs as a daemon and kills processes that go over their OOM score) installed?
dpkg -l '*oom*'
There are two most popular ones: earlyoom and oomd (now under systemd, I believe). I doubt a shell script would get such a bad OOM score from the kernel, but perhaps it's too intensive and gets killed by the daemon? I'd check that anyways.
Remember to edit the subject of your topic to include the [SOLVED] tag once you're satisfied with the answers or have found a solution (in which case, don't forget to share it as well), so that other members of the community can quickly refer to it and save their time. Pretty please!
Offline
I'm running Ubuntu-based Linux Lite 5.8 and Linux Mint Xfce 20.3
dpkg -l '*oom*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-===========================-============-============-========================================================================
un foomatic-db <none> <none> (no description available)
ii foomatic-db-compressed-ppds 20200401-1 all OpenPrinting printer support - Compressed PPDs derived from the database
ii foomatic-db-engine 4.0.13-4 amd64 OpenPrinting printer support - programs
un foomatic-db-gutenprint <none> <none> (no description available)
un foomatic-db-hpijs <none> <none> (no description available)
un foomatic-filters <none> <none> (no description available)
un foomatic-filters-beh <none> <none> (no description availab
Linux Mint Xfce 21.1
Offline
Hi ToZ, I put your latest script in place, sound was played, bubble showed up.
Now I'll keep an eye (I should say an ear) on it if it will stop again later.
Thank you!
Linux Mint Xfce 21.1
Offline
ToZ, computer has been running for over two hours now and script is still working, maybe we got it this time. However, if there is 4 files in trash, and I empty it, it plays the sound 4 times with 4 bubbles showing up. Very funny! Can it be fixed please?
Thanks
Linux Mint Xfce 21.1
Offline
Try this version:
#!/bin/bash
# requires inotify-tools
DIR="$HOME/.local/share/Trash/info"
LAST=$(date +%s)
# make sure that only one instance of this script is running per user
lockfile=/tmp/.trashsound.$USER.lockfile
if ( set -o noclobber; echo "locked" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
echo "trashsoundDEBUG: Locking succeeded" >&2
inotifywait -q -m -r -e delete $DIR | while read D E F; do
CURRENT=$(date +%s)
[[ $(( $CURRENT-$LAST )) -gt 3 ]] && play /home/shamu/My-sounds/trash-empty.wav
LAST=$CURRENT
done
# can't create lockfile - notify user and quit
else
echo "trashsoundDEBUG: Lock failed, check for existing process and/or lock file and delete - exiting." >&2
exit 1
fi
I've added a 3 second window for not playing sounds while files are being deleted and I've removed the notification bubble.
Please remember to mark your thread [SOLVED] to make it easier for others to find
--- How To Ask For Help | FAQ | Developer Wiki | Community | Contribute ---
Offline
This one will wait until everything is deleted from trash.
#!/bin/bash
# requires inotify-tools
DIR="$HOME/.local/share/Trash/info"
# make sure that only one instance of this script is running per user
lockfile=/tmp/.trashsound.$USER.lockfile
if ( set -o noclobber; echo "locked" > "$lockfile") 2> /dev/null; then
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
echo "trashsoundDEBUG: Locking succeeded" >&2
while : ; do
inotifywait -q -m -r -e delete $DIR | read
until [ -z "$(ls -A $DIR)" ]; do
sleep 0.1
done
play /home/shamu/My-sounds/trash-empty.wav
notify-send -i user-trash "Trash" "emtpy-trash sound should play"
done
# can't create lockfile - notify user and quit
else
echo "trashsoundDEBUG: Lock failed, check for existing process and/or lock file and delete - exiting." >&2
exit 1
fi
Edit: it was blocking sometimes, needed to use sleep to wait until the folder is empty.
(changed the script)
Last edited by Misko_2083 (2022-07-12 00:00:16)
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
ToZ, Misko, thank you very much both of you, you guys are sooo wonderful!
I put Misko's script in my Mint, after a reboot, right after signing in, it started playing the sound again and again, and never quit...the sound I'm using here is a shotgun sound. It was so funny, I felt like being in Ukraine in a battlefield. Tried to reboot 3 times, it happened every time.
I put ToZ's script in my Lite, it did work great, even when deleting 5 files, it played the sound once.
I love Linux, it's amazing what people like you guys can do with one little script.
Last edited by agashamu (2022-07-12 02:30:04)
Linux Mint Xfce 21.1
Offline
ToZ, Misko, thank you very much both of you, you guys are sooo wonderful!
I put Misko's script in my Mint, after a reboot, right after signing in, it started playing the sound again and again, and never quit...the sound I'm using here is a shotgun sound. It was so funny, I felt like being in Ukraine in a battlefield. Tried to reboot 3 times, it happened every time.
Sorry about that, sort of works here. inotifywait had some bug depending on the version.
ToZ's script plays when a singlew file is deleted from trash.
I found this https://www.opensourceforu.com/2011/04/ … h-inotify/
and addapted the code to watch and play mp3 file when the trash is empty.
Uses libao for the audio sink and libmpg123 to play mp3.
Depends:
libao-dev libmpg123-dev
Compiles with:
gcc watch-trash.c -o watch-trash -lmpg123 -lao
run with
./watch-trash /path/file.mp3
watch-trash.c
/*
watch-trash.c
play sound when trash is emptied
Code adapted from https://www.opensourceforu.com/2011/04/getting-started-with-inotify/
Depends:
libao libmpg123 (development libs)
Compile with:
gcc watch-trash.c -o watch-trash -lmpg123 -lao
Run with:
./watch-trash /path/file.mp3
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <limits.h>
#include <unistd.h>
#include <dirent.h>
#include <stdarg.h>
#include <ao/ao.h>
#include <mpg123.h>
#include <sys/file.h>
#include <errno.h>
#define PID_FILE "/tmp/.trashsound.lockfile"
#define BITS 8
#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
#define LEN_NAME 1024 /*Assuming length of the filename won't exceed 16 bytes*/
#define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/
#define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
char path[64];
int vspfunc (char *format, ...) {
va_list aptr;
int ret;
va_start (aptr, format);
ret = vsprintf (path, format, aptr);
va_end (aptr);
return (ret);
}
int number_of_files () {
int file_count = 0;
struct dirent * entry;
DIR * dirp;
dirp = opendir (path);
while ((entry = readdir(dirp)) != NULL) {
if (entry->d_type == DT_REG) { /* If entry is a regular file */
file_count++;
}
}
closedir(dirp);
return file_count;
}
void play_file (char *music) {
int driver, err;
ao_device *dev;
mpg123_handle *han;
unsigned char *buff;
size_t buffer_size;
size_t done;
ao_sample_format format;
int channels, encoding;
long rate;
ao_initialize();
driver = ao_default_driver_id();
mpg123_init();
han = mpg123_new (NULL, &err);
buffer_size = mpg123_outblock(han);
buff = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
mpg123_open (han, music);
mpg123_getformat (han, &rate, &channels, &encoding);
format.bits = mpg123_encsize (encoding) * BITS;
format.rate = rate;
format.channels = channels;
format.byte_format = AO_FMT_NATIVE;
format.matrix = 0;
dev = ao_open_live(driver, &format, NULL);
while (mpg123_read (han, buff, buffer_size, &done) == MPG123_OK)
ao_play(dev, buff, done);
free(buff);
ao_close(dev);
mpg123_close(han);
mpg123_delete(han);
mpg123_exit();
ao_shutdown();
}
void get_event (int fd) {
char buffer[BUF_LEN];
int length, i = 0;
length = read( fd, buffer, BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if ( event->len ) {
if ( event->mask & IN_DELETE) {
if (event->mask | IN_ISDIR) {
printf( "The file %s was deleted with WD %d\n", event->name, event->wd );
}
}
i += EVENT_SIZE + event->len;
}
}
}
int main( int argc, char **argv ) {
int wd, fd, n;
char * home = getenv("HOME");
char * trash = "/.local/share/Trash/info";
if(argc < 2)
exit(0);
int pid_file = open (PID_FILE, O_CREAT | O_RDWR, 0644);
int rc = flock (pid_file, LOCK_EX | LOCK_NB);
if (rc) {
if (EWOULDBLOCK == errno) {
printf ( "App is allready running\n" );
return 1;
}
}
vspfunc("%s%s", home, trash);
fd = inotify_init();
if ( fd < 0 ) {
perror( "Couldn't initialize inotify");
}
wd = inotify_add_watch(fd, path, IN_DELETE);
if (wd == -1) {
printf("Couldn't add watch to %s\n", path);
} else {
printf("Watching:: %s\n", path);
}
/* do it forever*/
while(1) {
get_event(fd);
n = number_of_files();
if (n < 1) {
play_file (argv[1]);
}
}
/* Clean up*/
inotify_rm_watch( fd, wd );
close( fd );
close( pid_file );
return 0;
}
Maybe the name off the app is bad but it doesn't sound like a machine gun.
Edit: now only one instance of app can start
Last edited by Misko_2083 (2022-07-12 12:32:57)
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
Thanks Misko_2083 for sharing this. I clicked on that link, and boy, oh boy...codes after codes and more codes. Wish I could understand any of those. I checked out your old posts here, wow, lots of scripts you have created, played with them with ToZ. You guys are great, not only helping out others, but enjoying Linux!! Good for you!!
I also noticed you are from Linux Lite. I love that distro, still running 5.8. Tried 6.0, but for me, the new Ubuntu version screwed it up. Can't install many little things that still running fine in 5.8.
Thank you Sir and have a great evening!
Linux Mint Xfce 21.1
Offline
played with them with ToZ.
OK, it's officially a bromance.
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
Misko is a genius, wherever he is, just helps and provide code.
Devuan/XFCE
Offline
Misko is a genius, wherever he is, just helps and provide code.
Right here Nili, but would never agree with the genius estimation.
Updated the App.
sound-empty-trash is more descriptive name for it I think.
Added some file checks, we want to make sure it's a file, not an executable and that we can read it.
Now it's playing whenever a file(s) is/are moved to or removed from trash.
It's recommended to use a short mp3, not an opera.
I use this one: https://orangefreesounds.com/empty-trash-sound-effect/ * “Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)”
Usage:
./sound-empty-trash /path/to/file.mp3
/*
sound-empty-trash.c
play sound when trash is emptied
Code adapted from https://www.opensourceforu.com/2011/04/getting-started-with-inotify/
Depends:
libao libmpg123 (development libs)
Compile with:
gcc sound-empty-trash.c -o sound-empty-trash -lmpg123 -lao
Run with:
./sound-empty-trash /path/file.mp3
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <limits.h>
#include <unistd.h>
#include <dirent.h>
#include <stdarg.h>
#include <ao/ao.h>
#include <mpg123.h>
#include <sys/file.h>
#include <errno.h>
#include <string.h>
#define PID_FILE "/tmp/.trashsound.lockfile"
#define BITS 8
#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
#define LEN_NAME 1024 /*Assuming length of the filename won't exceed 16 bytes*/
#define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/
#define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
char path[64];
int vspfunc (char *format, ...) {
va_list aptr;
int ret;
va_start (aptr, format);
ret = vsprintf (path, format, aptr);
va_end (aptr);
return (ret);
}
int number_of_files () {
int file_count = 0;
struct dirent * entry;
DIR * dirp;
dirp = opendir (path);
while ((entry = readdir(dirp)) != NULL) {
if (entry->d_type == DT_REG) { /* If entry is a regular file */
file_count++;
}
}
closedir(dirp);
return file_count;
}
void play_file (char *music) {
int driver, err;
ao_device *dev;
mpg123_handle *han;
unsigned char *buff;
size_t buffer_size;
size_t done;
ao_sample_format format;
int channels, encoding;
long rate;
ao_initialize();
driver = ao_default_driver_id();
mpg123_init();
han = mpg123_new (NULL, &err);
buffer_size = mpg123_outblock(han);
buff = (unsigned char*) malloc(buffer_size * sizeof(unsigned char));
mpg123_open (han, music);
mpg123_getformat (han, &rate, &channels, &encoding);
format.bits = mpg123_encsize (encoding) * BITS;
format.rate = rate;
format.channels = channels;
format.byte_format = AO_FMT_NATIVE;
format.matrix = 0;
dev = ao_open_live(driver, &format, NULL);
while (mpg123_read (han, buff, buffer_size, &done) == MPG123_OK)
ao_play(dev, buff, done);
free(buff);
ao_close(dev);
mpg123_close(han);
mpg123_delete(han);
mpg123_exit();
ao_shutdown();
}
void get_event (int fd) {
char buffer[BUF_LEN];
int length, i = 0;
length = read( fd, buffer, BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if ( event->len ) {
if ( event->mask & IN_CREATE) {
if (event->mask | IN_ISDIR)
printf( "The file %s was Created with WD %d\n", event->name, event->wd );
}
if ( event->mask & IN_DELETE) {
if (event->mask | IN_ISDIR) {
printf( "The file %s was deleted with WD %d\n", event->name, event->wd );
}
}
i += EVENT_SIZE + event->len;
}
}
}
int check_file (char *fPath) {
char * point;
if (access(fPath, F_OK) != 0) {
printf("The file '%s' does not exist\n", fPath);
return 1;
}
if (access(fPath, R_OK )){
printf("The File '%s' can't be read\n", fPath);
return 1;
}
if (!access(fPath, X_OK )){
printf("The File '%s' is an Executable\n",fPath);
return 1;
}
if ((point = strrchr(fPath,'.')) != NULL ) {
if (strcmp(point,".mp3") != 0) {
printf("Unknown file type %s\n", point);
return 1;
}
}
return 0;
}
int main( int argc, char **argv ) {
int wd, fd, n, new;
char * home = getenv("HOME");
char * trash = "/.local/share/Trash/info";
if (argc < 2) {
printf("Usage:\n\t%s 'file.mp3'", argv[0]);
return 1;
}
int pid_file = open (PID_FILE, O_CREAT | O_RDWR, 0644);
int rc = flock (pid_file, LOCK_EX | LOCK_NB);
if (rc) {
if (EWOULDBLOCK == errno) {
printf ( "App is allready running\n" );
return 1;
}
}
if (check_file(argv[1]))
return 1;
vspfunc("%s%s", home, trash);
fd = inotify_init();
if ( fd < 0 ) {
perror( "Couldn't initialize inotify");
return 1;
}
wd = inotify_add_watch(fd, path, IN_CREATE | IN_DELETE);
if (wd == -1) {
printf("Couldn't add watch to %s\n", path);
} else {
printf("Watching:: %s\n", path);
}
n = number_of_files();
/* do it forever*/
while(1) {
get_event(fd);
new = number_of_files();
if (n != new) {
play_file (argv[1]);
printf("Playing\n");
}
n = number_of_files();
}
/* Clean up*/
inotify_rm_watch( fd, wd );
close( fd );
close( pid_file );
return 0;
}
Edit: Added a video demo https://www.youtube.com/watch?v=iHMkIrQ76Xw
Last edited by Misko_2083 (2022-07-18 09:07:23)
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
This script is quite incredible Misko!
but would never agree with the genius estimation
How about: The King of Linux Script Writing
Linux Mint Xfce 21.1
Offline
This script is quite incredible Misko!
Misko wrote:but would never agree with the genius estimation
How about: The King of Linux Script Writing
It's actually written in C, and glad you like it.
I'm an ordinary guy occasionally visiting the forums.
ToZ and KBar are a better candidates for that title.
Do you want to exit the Circus?
https://www.youtube.com/watch?v=ZJwQicZHp_c
Offline
Right here Nili, but would never agree with the genius estimation.
Everytime you post codes or help people, especially those on yad, I have this impression about you.
Devuan/XFCE
Offline
[ Generated in 0.013 seconds, 8 queries executed - Memory usage: 681.66 KiB (Peak: 714.5 KiB) ]