0

I have a script that I've largely finished except for one issue I just can't seem to crack removing a linefeed character before it gets passed to zbarimg. I've tried various things looked around online and can't seem to find anything to get rid of this pesky character. Any help would be greatly appreciated.

#!/bin/bash
folder=~/Public

cdate=$(date +"%Y-%m-%d-%H:%M")

inotifywait -m -q -e create -r --format '%:e %w%f' $folder | while read file

  do
    ifile=$(ls -Art ~/Public | tail -n 1)
    ifile2=$(echo $ifile | tr '\n' ' ')
    echo $ifile2 >> /tmp/latest.txt
    zbarimg $ifile2 | pluma
  done

Output of ls -alrt (last few lines)

-rw-r--r--  1 mintux mintux   875988 Nov 11 12:42 20151111_114942.jpg
-rw-r--r--  1 mintux mintux   801317 Nov 11 12:45 20151111_114759(2).jpg
-rw-r--r--  1 mintux mintux   875988 Nov 11 12:45 20151111_114942(2).jpg
-rw-r--r--  1 mintux mintux      911 Nov 23 23:24 nov23.png
-rw-r--r--  1 mintux mintux    23158 Nov 23 23:43 nov23a.png
drwxr-xr-x 73 mintux mintux    24576 Nov 24 08:42 ..
drwxr-xr-x  4 mintux mintux     4096 Nov 24 12:10 .
  • Have you tried http://stackoverflow.com/questions/1654021/how-can-i-delete-a-newline-if-it-is-the-last-character-in-a-file – Ilya Kogan Nov 24 '15 at 04:59
  • 1
    It's hard to figure out what you are trying to accomplish without access to the input and the desired output. Your question would be much improved if you took away the `inotifywait` and `zbarimg` parts and just focused on the actual string modification. Anyway, `echo $ifile` without [proper quoting](http://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-variable) will already coincidentally lose any newlines, but probably the wrong ones. – tripleee Nov 24 '15 at 05:49
  • There is no `'\n'`. You can prove it to yourself `ifile=$(ls -Art ~/Public | tail -n 1); echo "'$ifile'"` What newline are you trying to remove with your `ifile2=` line? **Note:** in `echo $ifile2`, `echo` automatically adds the newline, use `echo -n $ifile2 >> /tmp/latest.txt` if you want no newline after `$ifile2`. – David C. Rankin Nov 24 '15 at 05:56

2 Answers2

0

You question is a bit unclear, but in your script below, there is no newline ('\n') at the end of either ifile or ifile2. While it is somewhat difficult to determine exactly what newline you are attempting to eradicate, it appears your goal is to prevent a newline from being written to /tmp/latest.txt following redirecting $ifile2 to the file. (that is the only conceivable newline at issue) The only newline involved in that entire transaction is the newline put there by echo itself:

#!/bin/bash

folder=~/Public

cdate=$(date +"%Y-%m-%d-%H:%M")

inotifywait -m -q -e create -r --format '%:e %w%f' $folder | while read file

do
    ifile=$(ls -Art ~/Public | tail -n 1)
    ifile2=$(echo $ifile | tr '\n' ' ')
    echo $ifile2 >> /tmp/latest.txt
    zbarimg $ifile2 | pluma
done

If you want no newline written to /tmp/latest.txt, then use echo -n or printf, e.g.:

#!/bin/bash

folder=~/Public

cdate=$(date +"%Y-%m-%d-%H:%M")

inotifywait -m -q -e create -r --format '%:e %w%f' "$folder" | while read -r file

do
    ifile=$(ls -Art ~/Public | tail -n 1)
    echo -n "$ifile" >> /tmp/latest.txt  # or printf "%s" "$ifile"
    zbarimg "$ifile" | pluma
done

Note: you can prove there is no newline to yourself with:

echo "'$ifile'"

Note2: In bash, unless inside [[...]] you should always quote your variables. (if you don't remember [[...]], then just always quote your variables). Further, the use of ls (any sort order) to fill your variable ifile is susceptible to a number of subtle file name errors (newlines in filenames, etc.) See Bash Pitfalls (#1) for related reasons involved in trying to iterate over the return of ls.


"when I manually run it outside of the script it opens it just fine but throws an error about being unable to open the file from with in it".

OK that makes more sense. One way to find the newest file in "$folder" without the pitfals inherent in parsing ls would be:

#!/bin/bash

folder=~/Public

cdate=$(date +"%Y-%m-%d-%H:%M")

inotifywait -m -q -e create -r --format '%:e %w%f' "$folder" | while read -r file

unset -v ifile
for fname in "$folder"/*; do
    [[ $fname -nt $ifile ]] && ifile="$fname"
done

zbarimg "$ifile" | pluma

Give that a try and let me know if that cures the issue.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • I mainly have the 'latest.txt' file there for debugging, what I'm really trying to do is prevent the new line character from being used with the zbarimg utility, it behaves as if the file I passed it has a new line character as when I manually run it outside of the script it opens it just fine but throws an error about being unable to open the file from with in it. – user1208273 Nov 24 '15 at 07:47
  • You have to be careful here. All files, according to the POSIX definition of a file, will have a `newline` terminating the content. That doesn't mean all files will meet the POSIX line-end requirement (you can force a file without a newline at the end), but all POSIX compliant utilities, etc. will expect one to be there. I will search for `zbarimg` and see if I can find anything that helps. I have never heard of it until now. Let me see what I can find. Your script (other than specified) isn't doing anything incorrectly, in fact writing without the newline is non POSIX in itself `:)` – David C. Rankin Nov 24 '15 at 07:53
  • @user1208273 *"when I manually run it outside of the script it opens it just fine but throws an error about being unable to open the file from with in it"*. OK, this is the real error at issue. You see the `Bash Pitfalls` comment in the last paragraph of the answer. I suspect that is where the problem is coming from. Which file do you want to choose from `~/Public` (the newest?). Let me know and we will work on alternative that does NOT include using `ls` and `tail` to select it. (by the way, the barcode scan `zbarimg` isn't the issue, it's the way you fill `ifile`) – David C. Rankin Nov 24 '15 at 08:00
  • yes, correct my intent is to run the newest file in that directory. – user1208273 Nov 24 '15 at 08:20
  • OK, look at the addition at the end of the answer as an alternative way to find the newest file. – David C. Rankin Nov 24 '15 at 08:25
  • seems to throw unexpected end of file error. Thanks again for your assistance. – user1208273 Nov 24 '15 at 09:05
  • Aargh -- this is now officially driving me nuts.. Just what type filenames are you storing in `~/Public`? Can you edit your question and give us the last 5 lines of `ls -alrt`? Also have you messed with your LOCALE setting? I take from `pluma` (pen? write? feather?) that your code/files may be set for a language other than US/UTF-8. If that is the case, let us know, that may give other ideas. There is no reason your `zbarimg` call should be any different when called from a script or from the command line. Something other than bash is going on here. – David C. Rankin Nov 24 '15 at 09:11
  • The ones stored range from .txt, .mp3, .html basically anything coming in from bluetooth connections, though zbarimg is getting passed png files which when I input them directly by calling zbarimg outside the script they are processed fine. Pluma is the MATE fork of gedit. – user1208273 Nov 24 '15 at 17:31
  • What I am concerned about is the first part of the filename. Since it is coming from a bluetooth connection, that raises suspicion further on just what they are comprised of. Seriously, a post of 10 lines or so of `ls -art` would help a lot. – David C. Rankin Nov 24 '15 at 17:56
  • would a full output of ls -alrt be more useful in diagnosing this? – user1208273 Nov 25 '15 at 00:08
  • I should also note the issue occurs even when I paste in files from elsewhere on the filesystem. – user1208273 Nov 25 '15 at 00:34
0

So after all that, turns out the real issue was I had just forgotten to append the folder to the file name so the reason zbarimg couldn't open the file had nothing to do with line feeds like I thought here is basically what fixed it:

zbarimg $folder/$ifile2

Thanks again to all those who offered help, sorry for the incompetence on my part may the blessing and forgiveness of the internet be upon me :)