Need some help with bash scripting.
Hello! :study:
Im trying to build and extend some scripts to reorganize my music collection. I do have basic knowlodge of bash, but sometimes i run into errors, which i can't seem to solve on my own - which (i guess) would farly simple to solve. My first question: Code:
#!/bin/sh The output: Code:
mainstream@dopamine-pc:~/Music$ ./foo.sh I tried adding " or ' but that trick doesn't seem to work though. Can anyone help? Thanks |
I know it has something to do with ` to escape the spaces, but i tried everything lol!
|
I'm not sure what you want to accomplish specifically here, so maybe you could show the output error and what you want the correct output to be
|
Quote:
|
The problem is that the list of arguments in the for statement is splitted by spaces (other than TABs and newlines, according to the default value of IFS) hence you will never see the complete file names inside the loop and the addtags function.
You can try to change field splitting behaviour, for example by setting IFS to newline: Code:
#!/bin/sh Code:
#!/bin/bash |
the above code works, just unset IFS after.
Code:
#!/bin/sh |
Unless there's more code, no need to unset IFS. It'll unset/revert when the script completes.
|
Well... actually the correct way is to save the default IFS and restore it later (if the script continues, as Chris notcied):
Code:
OLD_IFS="$IFS" |
Great that worked! Thanks allot for the help guys! I appreciate it!
OK, this is what i made for now: Code:
#!/bin/bash Code:
mainstream@dopamine-pc:~/Music$ bash foo.sh |
Nobody knows what's happening? :(
|
Quote:
Code:
#!/bin/bash Code:
#!/bin/bash -vx Code:
set -vx Code:
/bin/bash -vx /path/to/script Code:
find $DIR -name $TYPE | head -10 | while read ITEM; do |
That was my recommendation which is to do things like unSpawn has suggested:
- Always look for ways to debug steps, turning on -vx gives you output and progress of your script. - Set variables for the outcome of commands and check them, or specifically test the outcome of commands via $? - Always verify on the target system the paths to commands. Since I mostly do embedded, the structure of the paths is deterministic and further, there are no guarantees that all commands are available. So from the shell on the target system I make sure the command exists, is accessible via $PATH, and that I know the exact location where the command is; such as /bin, or /sbin and include the full path to the command within the script. And thanks to unSpawn, I hadn't known the various ways to control vx in scripts, I always add it as two lines: Code:
set -x |
Thanks for your help, that worked quite good.
I was already using set -vx (use it always), but as i already stated earlier: my bash programming knowledge is quite basic :-( |
UnSpawn beat me to it. As always, the real solution is:
Don't Read Lines With For! Seriously, it's such a common mistake, I think every time I come here I have to post this link 2 or 3 times. Word-splitting and globbing expansion are always an issue any time you try to include parameter and command expansions (including importing data from files) inside other commands. You only have two choices in such cases: you can keep everything together as a single argument by quoting them, or let the shell split it up everywhere it can. There's no completely safe way to split such data only where you want it to, except through use of a while+read loop, with null separators*. A few other links along the same lines* How can I read a file (data stream, variable) line-by-line (and/or field-by-field)? http://mywiki.wooledge.org/BashFAQ/001 How can I find and deal with file names containing newlines, spaces or both? http://mywiki.wooledge.org/BashFAQ/020 How can I rename all my *.foo files to *.bar, or convert spaces to underscores, or convert upper-case file names to lower case? http://mywiki.wooledge.org/BashFAQ/030 ( *Actually, a for loop on an array of individual lines/filenames would also work, but then the issue becomes first safely loading the array with the data. ;) ) |
Incidentally, I noticed your interesting take on parameter substitution in your rename function. Since many of the patterns use the same format, I'd like to recommend a modification to remove a lot of that duplication.
(I'm only going to post the relevant part of the function) Code:
rename() { By the way, you don't generally need to backslash-escape special characters when you first store them in variables like this, as long as you properly quote the strings when setting them and when expanding them. Unless the strings you're working on actually have backslashes in them? In other words, backslashes/quotes are only needed when protecting a character from direct shell parsing. Once a string is stored in a parameter, everything in it is treated literally, except for the word-splitting and globbing expansion that's done if unquoted. (To be specific, quotes and backslashes are processed before the parameter expansion step, but word-splitting and globbing happen after expansion). Finally, you should endeavor to explicitly scope function variables locally whenever possible. |
All times are GMT -5. The time now is 02:14 AM. |