From: Eero T. <ee...@us...> - 2008-03-27 10:22:32
|
Hi, On Thursday 27 March 2008, Dave Walton wrote: > > "Because the value of GRAMPSHOME is set on the same line as the command > > to run GRAMPS, that value is only used for that command" > > > > Correct, but... > > > > "and will not carry on past the end of the script." > > > > -> Unless one explicitly sources the script instead of executing it > > normally, its environment disappears when the script ends. > > I.e. it doesn't propagate (except to its gramps child process). > > I confess I'm a little weak on shell scripting. As I understand it, > variables set in the script are not available to GRAMPS unless they are > on the same line like this, or you use 'export'. Yes. > And if you use 'export', the variable goes into the global environment. "Global" environment of the current process and its children. It doesn't propagate to other processes of even the same user (among other things that would be a security hole as environment variables are used to control many dynamic library loading features of the Glibc dynamic linker, Gtk etc). > So setting it on the same line is necessary to both make it available to > GRAMPS Correct. You could use just export, but I think it's kind of nicer to have it on the same line. > and prevent it from propagating. Is that correct? Incorrect. > > "This is a little less forgiving than the Windows version, because bash > > doesn't have the equivalent of the Windows %0 modifiers. $0 only > > contains exactly what was used to start the script, so if you don't use > > the full path to the script (for example, if it's on the search path), > > the script has no way to determine where it is located. > > > > -> Both Bash and Dash in Ubuntu 7.04 gave full path for $0 regardless > > whether I called it with full path or not (and same happened from > > KDE desktop applink), so this comment seems also redundant...? > > > > (but I remember having problem like this many years ago, so maybe it > > that only older versions of shells.) > > I see what you mean. Perhaps the search path isn't an issue after all. > What about relative paths? They seem to appear exactly as typed, > which would cause GRAMPSHOME to be a relative path. Do you think it > would be ok to drop the 'cd' and allow GRAMPSHOME to be relative to pwd > (and perhaps even just '.')? Might that cause problems somehow? No idea. :-) > > Invoking "dirname" in subshell can be be replaced just with: > > DIRNAME=${0%/*} Better have it quoted here too just in case: DIRNAME="${0%/*}" > > This works in Bash, Dash and Busybox shell so I believe it's POSIX. It's POSIX: http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02 > Interesting. Can you explain what that does and how it works? ${<variable>} is a more "formal" way to refer to variables, you need it in situations where shell doesn't know where the variable names ends, like in: echo "${foo}bar" But shell allows you also to have some modifiers for the variable value. '%' is used to remove parts from the end of the variable value, '#' from the beginning. What is removed is specified after that character and it's a so called shell "glob" pattern (I.e. supports '*', '?' and '[]'). If you use two '%' or '#' characters, the pattern is "greedy" i.e. instead of a shortest match, it removes the longest match for the given pattern. So... "${0%/*}" means: - take the value of variable $0 - remove from the end ('%') part of it... - ...the part matching to glob pattern "/*" i.e. the last '/' character and anything following it. I use this often for copying&renaming files, you could even make a generic rename script like this: ----- ren ----- #!/bin/sh if [ $# -ne 2 ]; then echo "usage: ren ext1 ext2" echo "renames files ending with ext1 to end with ext2" exit 1 fi for i in *.$1; do mv $i ${i%$1}$2 done -------------- I also use often the greedy prefix replace modifier instead of calling basename binary: name=${path##*/} For more information, see "man bash" and the "Parameter Expansion" section. Some other shell tips... * Use "$()" instead of backticks ("`") to run subshell. Unlike backticks, you can use that recursively and it's easier to find on foreign or virtual keyboards * If you don't have Python available, shell can also be used as a simple calculator: "echo $((1+2*3))" :-) > > IMHO it would be cleaner to forward the options given to the script > > also to Gramps i.e. add "$*" after $GRAMPS_COMMAND. > > Agreed. Without the quotes, right? Right. If user gave args with spaces, it doesn't work correctly anyway. :-) > > Running Gramps > > in background makes the script behave semantically different from > > invoking Gramps directly, so I would remove '&'. (The return value > > from script is the value of last command, so that already works OK.) > > Makes sense. You can always background the script with &, anyway. Done. > > Thanks for the feedback, Eero! - Eero |