cut loadable outputs extra newlines
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: darwin20.6.0 Compiler: gcc Compilation CFLAGS: -g -O2 uname output: Darwin macspear 20.6.0 Darwin Kernel Version 20.6.0: Tue Apr 19 2$ Machine Type: x86_64-apple-darwin20.6.0 Bash Version: 5.2 Patch Level: 0 Release Status: rc3 Description: examples/loadables/cut.c uses zgetline, which includes the newline delimiter in the line it reads, but the rest of the code expects the line to not contain the newline. Repeat-By: $ ./bash -c 'enable -f examples/loadables/cut cut ; cut -c4-' <<< $'abcdef\nghijkl' def jkl $ Fix: Strip off the newline right after reading the line. Attached patch fixes the problem. diff --git a/examples/loadables/cut.c b/examples/loadables/cut.c index ed4972d2..280c5231 100644 --- a/examples/loadables/cut.c +++ b/examples/loadables/cut.c @@ -417,6 +417,8 @@ cutfile (v, list, ops) while ((n = zgetline (fd, &line, &llen, '\n', unbuffered_read)) != -1) { QUIT; + if (line[n] == '\n') + line[n] = '\0'; cutline (v, line, ops); /* can modify line */ } if (fd > 0)
Feature request - make type show that a builtin is a loadable
I think it's a good idea for the type builtin to distinguish between static and loadable builtins, and for debugging scripts that use loadable builtins, it would be useful to be able to see which file got loaded. For example in cases where BASH_LOADABLES_PATH was unintentionally unset or set to a wrong path. I had a go at implementing it and cobbled together the attached patch. It extends struct builtin with a new path field that gets set to the path that was passed to dlopen. The type builtin then includes that path in its output if it is set. $ ./bash -c 'enable csv; type [ csv' [ is a shell builtin csv is a shell builtin (/usr/local/lib/bash/csv) $ BASH_LOADABLES_PATH=$PWD/examples/loadables ./bash -c 'enable csv; type [ csv' [ is a shell builtin csv is a shell builtin (/Users/geirha/bash/examples/loadables/csv) Continuing on the debugging aspect, I think it would also be useful if enable would warn or fail if you try to enable a loadable builtin that was built against a different bash version. The easiest is probably to embed the bash version inside the loadable file somehow, and compare that when loading. Giving something like: $ enable csv bash: enable: /usr/local/lib/bash/csv: builtin was built for bash-5.1.16 Not sure how to go about implementing that though, or if it's even a good approach. After all, you could potentially have multiple bash builds of the same version with different configure options, which could potentially leave out some function the loadable builtin expects to use. -- Geir Hauge diff --git a/builtins.h b/builtins.h index 01565935..b4c71274 100644 --- a/builtins.h +++ b/builtins.h @@ -57,6 +57,7 @@ struct builtin { char * const *long_doc; /* NULL terminated array of strings. */ const char *short_doc; /* Short version of documentation. */ char *handle;/* for future use */ + char *path; /* path of loadable builtin. */ }; /* Found in builtins.c, created by builtins/mkbuiltins. */ diff --git a/builtins/enable.def b/builtins/enable.def index 27d341a6..ae861b96 100644 --- a/builtins/enable.def +++ b/builtins/enable.def @@ -340,6 +340,7 @@ dyn_load_builtin (list, flags, filename) #endif handle = 0; + load_path = 0; if (absolute_program (filename) == 0) { loadables_path = get_string_value ("BASH_LOADABLES_PATH"); @@ -353,7 +354,6 @@ dyn_load_builtin (list, flags, filename) #else handle = dlopen (load_path, RTLD_LAZY); #endif /* !_AIX */ - free (load_path); } } } @@ -377,6 +377,8 @@ dyn_load_builtin (list, flags, filename) if (name != filename) free (name); } + if (load_path) +free (load_path); return (EX_NOTFOUND); } @@ -434,6 +436,7 @@ dyn_load_builtin (list, flags, filename) if (flags & SPECIAL) b->flags |= SPECIAL_BUILTIN; b->handle = handle; + b->path = load_path ? savestring(load_path) : NULL; if (old_builtin) { @@ -444,6 +447,9 @@ dyn_load_builtin (list, flags, filename) new_builtins[new++] = b; } + if (load_path) +free (load_path); + if (replaced == 0 && new == 0) { free (new_builtins); diff --git a/builtins/type.def b/builtins/type.def index a8e47c0a..fc7099db 100644 --- a/builtins/type.def +++ b/builtins/type.def @@ -52,6 +52,7 @@ $END #include +#include "../builtins.h" #include "../bashtypes.h" #include "posixstat.h" @@ -289,6 +290,7 @@ describe_command (command, dflags) } /* Command is a builtin? */ + struct builtin *b = builtin_address_internal(command, 0); if (((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command)) { if (dflags & CDESC_TYPE) @@ -297,6 +299,8 @@ describe_command (command, dflags) { if (posixly_correct && find_special_builtin (command) != 0) printf (_("%s is a special shell builtin\n"), command); + else if (b->path) + printf (_("%s is a shell builtin (%s)\n"), command, b->path); else printf (_("%s is a shell builtin\n"), command); }
Re: bug? {1..3} doesnt' use IFS to separate fields
2011/7/25 Linda Walsh > > > I know it wasn't designed this way, but it seems like it > is a bug. > The manual says nothing about brace expansion using IFS in any way, so it's not a bug. If I do > read a b c <<<$(echo {1..3} ); echo "a:$a b:$b c:$c" > I get: > a:1 b:2 c:3 > > But If I do > export IFS=','; read a b c <<<$(echo {1..3} ); echo "a:$a b:$b c:$c" > I get: > a:1 2 3 b: c: > > Why should the 2nd case return the wrong answer? > I.e. shouldn't {1..3} use the IFS to separate arguments? > I don't see the usefulness in having brace expansion's behavior changed by IFS. If you want {1..3} to turn into the string "1;2;3", assign it to an array, then print the array that way array=( {1..3} ) (IFS=';'; echo "${array[*]}") # outputs "1;2;3" printf -v var '%s;' "${array[@]}"; echo "$var" # outputs "1;2;3;" -- Geir Hauge
Re: invoke tilde expansion on quoted string
2011/11/12 Chris F.A. Johnson > On Fri, 11 Nov 2011, Peng Yu wrote: > >> I'm wondering if I already have a string variable, is there a bash >> native to do tilde expansion on it. >> >> var='~/..' >> cd $var#how to change this line? >> > > eval "cd $var" > I'd avoid eval as that could potentially do more than just expand the tilde, depending on what other characters the var contains. I'd just replace the ~ with $HOME using parameter expansion. cd "${var/#~\//$HOME/}" -- Geir Hauge
Re: exit status issue
2011/11/17 Dallas Clement > > Would appreciate any insight you could offer. Here is my script and > the strace output for when touch returns 1. > Add ''set -x'' at the start of the function and examine the output to see if it actually runs touch from PATH. -- Geir Hauge
Re: '>;' redirection operator [was: [1003.1(2008)/Issue 7 0000530]: Support in-place editing in sed (-iEXTENSION)]
2011/12/22 Bruce Korb > > When the exact opposite is the useful variation? I.e. keep-on-failure. > "-i" for sed is simple, understandable and implemented a lot. > As far as I know, -i is only implemented with GNU sed and BSD sed, and they are incompatible, BSD sed's -i takes a mandatory argument, while GNU sed's -i takes an optional string which must be provided in the same argument. E.g. gnused -i.bak sed-script file bsdsed -i .bak sed-script file So the only portable way of using sed to "edit" (read: overwrite) a file is with sed sed-script file > file.tmp && mv file.tmp file I'd welcome this >; syntax. -- Geir Hauge
Re: TAB vs. colon
2011/12/30 > But sometime we don't type in the path by hand, but instead paste it in > from elsewhere via the mouse or something. In this case we have to > painfully add the \ \ stuff by hand before any TAB expansion works. > A workaround would be to quote the path. E.g. instead of ls u do ls ''u -- Geir Hauge
Re: compgen is slow for large numbers of options
2012/3/19 Chet Ramey : > I will look at optimizing that function, but it's always going to take time > to plow through 300K when you have to split it into words. (There's not > actually any word splitting of consequence happening with your second > example using the pipeline.) Letting compgen do the command substitution speeds it up considerably $ TIMEFORMAT=%R $ time compgen -W "`seq 1 50`" 1794 >/dev/null 175.253 $ time compgen -W '`seq 1 50`' 1794 >/dev/null 2.347 -- Geir Hauge
Re: handling of test == by BASH's POSIX mode
2012/5/27 Jon Seymour : > Is there a reason why bash doesn't treat == as an illegal test > operator when running in POSIX mode? POSIX does not say == is not allowed. POSIX tells you what the shell should at least be able to do. A POSIX compliant shell can have whatever other features it likes, as long as the POSIX features are covered. > This is problematic because use of test == in scripts that should be > POSIX isn't getting caught when I run them under bash's POSIX mode. > The scripts then fail when run under dash which seems to be stricter > about this. Don't use non-POSIX features in a POSIX script, and you'll be fine. http://www.opengroup.org/onlinepubs/9699919799/utilities/contents.html -- Geir Hauge
Re: Redirect a backgrounded process' stdout toward COPROC's stdin
2012/6/3 Davide Baldini : > Description: > In the following test script I run an elementary coprocess to which the > echo built-in, run in background, attaches its standard-output: > > #!/bin/bash > # TEST 1 > coproc /bin/sleep 100 > echo >&${COPROC[1]} & > > The script always fails, for no apparent reason, giving the output: > > ./test.sh: line 4: ${COPROC[1]}: Bad file descriptor The coproc fds are only available in the same shell. The subshell created with & cannot use them. > I wonder if the correct syntax should be rather this one (ampersand > moved before redirection): > > #!/bin/bash > # TEST 2 > coproc /bin/sleep 100 > echo & >&${COPROC[1]} This is equivalent to echo & >&${COPROC[1]} & ends the command, so the redirection is not applied to the echo. See http://wiki.bash-hackers.org/syntax/keywords/coproc -- Geir Hauge
Loadables fail to build in devel branch
The code for the cut and getconf loadables under examples/loadables has apparently been removed, but the Makefile hasn't been updated accordingly. See attached patch. -- Geir Hauge removed_loadables.patch Description: Binary data
Re: PS1 multiline with colors
2013/7/9 Dan Douglas > Can also give all the debug output %q formatting. > > exec {BASH_XTRACEFD}> >(set +x; while IFS= read -r x; do printf %q\\n > "$x"; done) Note that {BASH_XTRACEFD}>... won't work in bash 4.2 (or older). It's fixed for the next release though. http://lists.gnu.org/archive/html/bug-bash/2012-09/msg6.html -- Geir Hauge
Re: Another "set" option?
2013/7/10 Bruce Korb > This seems like a lot of obtuse bother: > > xtrace_setting=$( >re=$'\nxtrace[ \t]+on' >[[ $(set -o) =~ $re ]] && echo ' -x' || echo ' +x') > > if there were only some magic like ${BASH_SETTING_XTRACE} or > xtrace_setting=$(set -q xtrace) or something. Could we get > something fairly straight forward for querying set/shopt state? > Thank you for considering. Regards, Bruce > shopt -qo xtrace && xtrace=1 -- Geir Hauge
Invalid extglob causes segfault with help builtin.
Configuration Information [Automatically generated, do not change]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 uname output: Linux sikozu 3.2.0-40-generic #64-Ubuntu SMP Mon Mar 25 21:22:26 UTC 2013 i686 i686 i386 GNU/Linux Machine Type: i686-pc-linux-gnu Bash Version: 4.2 Patch Level: 45 Release Status: release Description: One of the side-effects of the latest changes of the help builtin in the devel release is that ''help "(("'' no longer shows the help for (( ... )), so I casually threw some asterisks around it ... and got a segfault. This also happens in bash 4.2.45 and 4.2.25, but not 3.2.48. It only segfaults when extglob is enabled; probably because it's an incomplete extglob. Repeat-By: bash -O extglob -c 'help "*((*"' -- Geir Hauge
Typos and other issues with the documentation
Here's a list of a few problems with the documentation I've encountered lately: 1. The -n option introduced in 4.3-alpha for the wait builtin is mistyped as --n in the manual. 2. A minor typo in the help text for the hash builtin: $ help hash | grep ' -p' -p pathname use PATHNAME is the full pathname of NAME 3. In the manual, the section on Programmable Completion contains the following example: _completion_loader() { . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124 } complete -D -F _completion_loader If you add a couple of files defining completions for a couple of commands in /etc/bash_completion.d/ and then run the above example, completion will stop working for all other commands. I suggest adding -o default on that complete -D command so that it falls back on default completion if there's no completion defined for a given command. In addition I'd suggest dropping the .sh extension since .sh suggests the file contains sh code, but it surely will contain bash specific code. The path already suggests that it will contain bash completion code, so any extension would be redundant anyway. 4. The description for TIMEFORMAT in the manual says that if the variable is not set, bash acts as if it has the value $'\nreal\t%3lR\nuser\t%3lU\nsys%3lS'. There's missing a \t after sys there. In the devel branch there's an added backslash, but still missing the t. 5. The help text for most (if not all) example/loadables/ get "polluted" if the text is translated. *.po files generally contain a block like: msgid "" msgstr "" "Project-Id-Version: bash 4.2\n" "Report-Msgid-Bugs-To: \n" ...info about who translated it to the language and when etc... And if ''long_doc'' in ''struct builtin'' contains an empty string, that empty string gets translated into the above msgstr. So I suggest avoiding translating the empty string. I'm attaching patches against the latest git devel branch for the above five typos/bugs/suggestions. -- Geir Hauge 0001-wait-n.patch Description: Binary data 0002-help-hash-use-PATHNAME-is-the-full.patch Description: Binary data 0003-completion_loader-example.patch Description: Binary data 0004-Default-TIMEFORMAT.patch Description: Binary data 0005-Empty-string-translation.patch Description: Binary data
Re: Inaccurate modification date testing
2013/8/14 Jacek Krüger > Bash is innacurate when testing modification dates. It ignores fractions > of a second. Is it expected? Coreutils test does it properly. > Looks like that is fixed in 4.3-alpha http://git.savannah.gnu.org/cgit/bash.git/tree/CHANGES?h=devel#n554 -- Geir Hauge
Re: && operator prevents backgrounding over ssh
2013/9/26 Hinrik Örn Sigurðsson > The "&&" operator in bash seems to inhibit backgrounding when run over > ssh. You can try it with the following: > > ssh localhost "cd /tmp && nohup sleep 10 >/dev/null 2>&1 &" > > The above command will wait for sleep(1) to finish before returning. > If it is run without ssh, it returns immediately. Furthermore, other > shells such as dash and zsh will return immediately regardless of > whether ssh is used. > Probably because it's equivalent to { cd /tmp && nohup sleep 10 >/dev/null 2>&1; } & so the backgrounded process still have stdout and stderr connected to ssh. This should do what you want: cd /tmp && { nohup sleep 10 >/dev/null 2>&2 & } -- Geir Hauge
Re: The default value of TIMEFORMAT is incorrectly formatted
2013/11/2 Chet Ramey > On 11/1/13, 5:54 PM, Seungbeom Kim wrote: > > Description: > > The default value of TIMEFORMAT is incorrectly formatted: > > it is shown as $'\nreal\t%3lR\nuser\t%3lU\nsys%3lS' in the man > page, > > but it should be $'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'. > > Thanks for the report. This has already been fixed for bash-4.3. > I reported this a while back too, and it is changed in the latest devel branch, but it appears you introduced a different typo: $'\nreal\t%3lR\nuser\t%3lU\nsys\tt%3lS' -- Geir Hauge
Re: read builtin is not honoring -t argument
2013/12/11 > > Description: > read builtin is not honoring -t argument > > Repeat-By: > Just run 'read -t1' and note that the behavior seems not different > from simply running 'read' without arguments. > What does ''type read'' say? perhaps you have a function or alias by that name. I can't reproduce it either. -- Geir Hauge
${assoc[key]+set} no longer works.
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 uname output: Linux gina 3.2.0-59-generic #90-Ubuntu SMP Tue Jan 7 22:43:51 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.3 Patch Level: 0 Release Status: release Description: With an associative array, assoc, ${assoc[key]+set} expands to the empty string if the associated value is the empty string. Repeat-By: $ declare -A assoc='([x]= [y]="1" )' $ printf '<%s>\n' "${assoc[x]+x is a key}" "${assoc[y]+y is a key}" <>
Re: ${assoc[key]+set} no longer works.
2014-03-18 16:19 GMT+01:00 Chet Ramey : > On 3/18/14 5:36 AM, geir.ha...@gmail.com wrote: > > > Bash Version: 4.3 > > Patch Level: 0 > > Release Status: release > > > > Description: > > With an associative array, assoc, ${assoc[key]+set} expands to the > > empty string if the associated value is the empty string. > > Thanks for the report. This was a consequence of a change made back in > 2011 to expand the value portion of the assignment statement a slightly > different way. I've attached a patch to fix it. Thanks. That patch also makes [[ -v assoc[x] ]] return 0. However, [[ -v assoc ]] returns 1 (which it also does before the patch). Sounds related to this bug. -- Geir Hauge
Re: sourcing script file from inside a function doesn't work anymore
2014-05-12 14:11 GMT+02:00 Greg Wooledge : > On Sat, May 10, 2014 at 12:22:40PM +0200, thioroup8 wrote: > > Now, I source it from inside a function: I obtain following error > message: > > bash: declare: tmp: not found > > I think this problem raises in the particular case of involving array > > variables definitions inside sourced bash script file... > > > cat << "EOF" > "${file_to_be_sourced}" > > declare -a tmp='([0]="1" [1]="2")' > > EOF > > The problem is that you are using "declare" within the file-to-be-sourced. > When you source the file inside a function, Bash runs the declare command > within the context of the function, where declare has the same meaning as > "local". Thus, it makes the variable local to the function. There really is a bug here, a weird one. Using a simplified script, we see that this works as expected: $ source <(printf "declare -a array='(x)'; declare -p array\n") declare -a array='([0]="x")' Wrapping it in a function should yield the same output, but doesn't: $ f() { source <(printf "declare -a array='(x)'; declare -p array\n"); }; f bash: declare: array: not found And while declare -p array fails to "find" the array, declare -p (without a name) does list it: $ f() { source <(printf "declare -a array='(x)'; declare -p array; declare -p | grep array= \n"); }; f bash: declare: array: not found declare -a array='([0]="x")' Oddly, the quotes seem to matter; changing array='(x)' to array=(x) makes it work... $ f() { source <(printf "declare -a array=(x); declare -p array\n"); }; f declare -a array='([0]="x")' -- Geir Hauge
Re: Segmentation fault bash 4.3.022
2014-08-11 20:47 GMT+02:00 Greg Wooledge : > On Tue, Aug 12, 2014 at 02:21:18AM +0800, lolilolicon wrote: > > The following code segfaults when run by bash 4.3.022 > > > > set -E > > shopt -s lastpipe > > trap -- 'true' ERR > > true | { true | false; } > > I could not reproduce this, on HP-UX or Linux. I tried from an > interactive shell, just typing these commands. Did you use a script? > Is your bash 4.3.22 from an OS distribution package, or did you compile > it yourself? If it's a script, is BASH_ENV set? Can you still trigger > the bug with an interactive shell, or with an interactive shell started > with --norc? > I can reproduce this on linux for non-interactive bash (which makes sense since lastpipe doesn't do much when set -m is in effect), but it's not limited to 4.3.22, and set -E does not appear to affect the outcome. $ bash42 -c 'echo "$BASH_VERSION";shopt -s lastpipe; trap -- "printf x" ERR; true | { true | false; }' 4.2.47(2)-release xxSegmentation fault $ bash43 -c 'shopt -s lastpipe; trap -- "printf x" ERR; true | { true | false; }' 4.3.22(1)-release xxSegmentation fault And lastly, in interactive mode $ set +m; shopt -s lastpipe; trap -- "printf x" ERR; true | { true | false; } xxx Can't quite understand why it would trigger the ERR trap thrice. -- Geir Hauge
Re: Issues with exported functions
2014-09-25 6:23 GMT+02:00 Linda Walsh : > > Maybe exporting fun? > > export fun='() { :;}' >> bash -c 'declare -pf fun' >> > bash: line 0: declare: fun: not found > ... > I've never seen functions created with an assignment. Is this a > new syntax in 4.3? > > (still in 4.2.43 here)... Bash has had this feature since "forever" $ fun='() { echo "$BASH_VERSION";}' bash1 -c fun 1.14.7(1) Your bash 4.2.43 is no exception, but the way declare's -p and -f options interact did change in 4.3, so try with just ''declare -f fun'' instead -- Geir Hauge
Re: Issues with exported functions
2014-09-25 10:43 GMT+02:00 Davide Brini : > I'm not arguing about anything, I just have a question. I understand that > with the current method used to export functions, it is not possible to > export a variable to a child whose value begins exactly with the characters > in question. A quick test seems to confirm that: > > $ x='() { echo a; }' bash -c 'echo "$x"' > > $ x='() { echo a; }' bash -c 'echo "$x"' > () { echo a; } > > > So is there a way to be able to export variables with arbitrary values, > including '() {' ? Sorry if this has been discussed before. > There's the -p flag, but it has other side effects $ x='() { echo a; }' bash -pc 'echo "$x"' () { echo a; } I also dislike that it parses exported functions by default; it violates the "don't treat data as code" rule. Sure would be nice if there was a separate flag that only disables parsing of exported functions. -- Geir Hauge
Re: ~/.profile and ~/.bash_profile aren't executed on login
On Sun, Dec 10, 2017 at 07:22:36PM -0800, Yuri wrote: > It only calls ~/.profile when it is named 'sh'. In posix mode, bash only looks for ~/.profile, but when you run it in non-posix mode, it will look for ~/.bash_profile and ~/.bash_login first. You probably have a ~/.bash_profile in addition to ~/.profile. Assuming this is the case, I suggest you merge whatever it contains into ~/.profile, and remove the ~/.bash_profile file. -- Geir Hauge
Can't wait for process substitution redirected for a subshell
Waiting on a process substitution that is used in redirection for a command grouping works, but not when using a subshell in place of that command grouping: $ TIMEFORMAT=%R $ time bash -c '{ :; } 2> >(sleep 2); wait "$!"' 2.013 $ time bash -c '(:) 2> >(sleep 2); wait "$!"' bash: line 0: wait: `': not a pid or valid job spec 0.008 I'd expect those two cases to behave the same way. It looks like the redirection is done after the subshell is forked, so adding the wait inside the subshell actually works: $ time bash -c '(echo "subshell \$! = $!"; wait "$!") 2> >(echo "procsub pid = $BASHPID"; sleep 2)' subshell $! = 74756 procsub pid = 74756 2.014 I get the same behavior with both 4.4.19 and the latest devel snapshot -- Geir Hauge
Re: Issue with Bash-4.3 Official Patch 27
2014-10-16 15:09 GMT+02:00 Chet Ramey : > On 10/15/14, 1:49 PM, lorenz.bucher@rohde-schwarz.com wrote: > > > But anyway. > > In my opinion I should trust a shell not violating their own rules and be > > able to import their own variables. > > That's not the issue. The shell can import variables like that just fine, > as evidenced by exported functions actually working. The question is > whether or not `export' lets you set and export non-identifiers. It does > and should not. > > > So the % character should be allowed to be used in variable names. > > No, shell variable names should continue to be shell identifiers. You > can already use `%' (any character, really) in environment variable > names. Regardless though, shouldn't source <(declare -xp) work whether or not the environment contains invalid identifiers? It doesn't at present: $ env %=% bash -c 'echo "$BASH_VERSION"; source <(declare -xp)' 4.3.30(1)-release /dev/fd/63: line 1: declare: `%': not a valid identifier Isn't declare -p output meant to be reusable as shell input? -- Geir Hauge
Re: feature: time builtin and file descriptor
2014-10-29 15:09 GMT+01:00 Sami Kerola : > > This idea came to my mind while writing a script that runs multiple > commands, and I simply wanted to know how long they are busy. I am > aware alternatives exist, but they can get a bit tricky if one wants to > have multiple measurements going on simultaneously. For example: > > exec 42>&0 > time --file-descriptor 42 > for i in items; in > exec 52>&0 > time --file-descriptor 52 > echo "processing $i" > [...] > echo "item $i took" > exec 52>&- > done > echo 'all together took:' > exec 42>&- > You could achieve this by using command grouping and TIMEFORMAT: items=( a b c ) time { for i in "${items[@]}"; do time { echo "processing $i" sleep "$((RANDOM%5 + 1))" TIMEFORMAT="item $i took %R seconds" } done TIMEFORMAT='all together took: %R seconds' } example output: processing a item a took 5.001 seconds processing b item b took 1.001 seconds processing c item c took 3.001 seconds all together took: 9.004 seconds It would be prettier if TIMEFORMAT could be set on invocation of time, e.g. TIMEFORMAT='foo took %R seconds' time { ...; } , but time being a keyword probably makes that hard. One also has to be careful to sanitize any variables one embeds in TIMEFORMAT since % characters are special. -- Geir Hauge
Re: BASH_FUNC__ appearing in environment
2014-11-28 9:43 GMT+01:00 steveT : > OK - found the functions that are appearing. I was grepping BASH_FUNC__ in > etc - wrong. The functions are in the /usr/share/bash-completion/completions > directory - and exist as rcs and sudo files. The code in those files > defines functions for _rcs and _sudo respectively. The rcs file contains: > > # bash completion for rcs -*- > shell-script -*- > > _rcs() > { > [--snipp--] > } && > complete -F _rcs ci co rlog rcs rcsdiff > > # ex: ts=4 sw=4 et filetype=sh > > OK - so that is the code that appears in my environment as BASH_FUNC__rcs > - now the question is - why - and why does it persist? I am not aware of > using completion with sudo or rcs - so where/why/how in bash do these > /usr/share scripts get actioned? > The third-party bash-completion package sets a "default completion function" (see it with complete -p -D; declare -f _completion_loader) that dynamically loads completions. For instance, if you do $ rcs TAB And there is not already a completion loaded for rcs, It will look for /usr/share/bash-completion/completions/rcs, source it if it finds it, then use the new completion. This in itself will not cause the function to be exported. I can only think of two ways of the function being exported, and that's by 1. specifically exporting it with ''export -f _rcs'' or ''declare -xf _rcs'' 2. you happen to run ''set -a'' at some point before the completion function gets dynamically loaded. When ''set -a'' is in effect, all variables and functions you define get automatically exported. If the output of ''echo "$-"'' contains 'a', then it is in effect. -- Geir Hauge
Re: Does [ -f FILE ] have a bug on testing a symlink ?
2015-02-09 22:00 GMT+01:00 Cheng Rk : > According this documentation `help test`, I am expecting it should return > false on anything other than a regular file, > > -f FILETrue if file exists and is a regular file. > > > but why it returned true on a symlink to a regular file? > > $ [ -f tmp/sym-link ] && echo true > true > The manual has this in addition: «Unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself.» http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions Probably wouldn't hurt to include that in the help text for the test builtin as well. -- Geir Hauge
mapfile segfaults when unsetting array in callback
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 uname output: Linux shbot 3.13.0-44-generic #73-Ubuntu SMP Tue Dec 16 00:22:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.3 Patch Level: 33 Release Status: release Description: When using mapfile's callback feature, and the callback unsets the array mapfile is appending to, it segfaults. Repeat-By: callback() { unset MAPFILE; } (mapfile -c 1 -C callback <<< x) -- Geir Hauge
Re: unset does not act as expected on namerefs
On Tue, May 26, 2015 at 11:24:57AM -0400, Shawn Wilson wrote: > On +2015/05/26 11:04:38, Greg Wooledge wrote: > > On Tue, May 26, 2015 at 10:31:34AM -0400, Shawn Wilson wrote: > > > swilson@swlap1:~/temp$ bash --version > > > GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu) > > > swilson@swlap1:~/temp$ cat t.txt > > > $ome text !n a file| > > > swilson@swlap1:~/temp$ unset t > > > swilson@swlap1:~/temp$ t=$(< ./t.txt) > > > swilson@swlap1:~/temp$ echo "$t" > > > bash: $ome text !n a file|: invalid variable name for name reference > > > swilson@swlap1:~/temp$ var=foo; declare -n t; t=var; unset t; echo "$t" > > > bash: $ome text !n a file|: invalid variable name for name reference > > > > As surprising as that is, have a look at "help unset": > > > > So current behavior should stand? I would think that unset (with no > options) should DWIM. This behavior also seemed to surprise most on > #bash IRC. This is not a bug for lack of documentation or not > understanding the results after looking at the doc, but a "wow, this > is surprising - maybe this could behave in a manner so it's not so > surprising". The surprising part is that it keeps the -n flag, but partially loses the nameref ability: $ var=foo; declare -n ref $ ref=var $ printf '%s - ' "$ref"; declare -p ref foo - declare -n ref="var" $ unset ref $ ref=var $ printf '%s - ' "$ref"; declare -p ref var - declare -n ref="var" $ ref=baz baz - declare -n ref="var" -- Geir Hauge
Re: unset does not act as expected on namerefs
On Tue, May 26, 2015 at 11:00:45AM -0500, Eduardo A. Bustamante López wrote: > # Here we 'unset ref', which actually unsets 'var'. Then, we assign 'var' to > # 'ref', but since 'ref' is still a nameref, it instead assigns 'var' to > 'var'. > dualbus@hp:~$ unset ref; ref=var; echo "$ref"; declare -p ref > var > declare -n ref="var" > dualbus@hp:~$ declare -p var > declare -- var="var" Ah, that explains it! Mystery solved, and no longer surprising behavior. -- Geir Hauge
Re: substitution "read all from fd" silently fails: $(<
On Wed, Jul 01, 2015 at 10:19:10PM +0300, Ilya Basin wrote: > Hi list. > > Want to read whole stdin into variable. > Don't want to spawn new processes (cat). > Don't want to reopen existing fd &0 > > First thing I tried: $(<&0) > It silently returns an empty string. This type of query is preferably asked at the help-bash list rather than bug-bash. > # works, but too complex > [root@okdistr ~]# echo aaa | sudo -u nobody bash -c 'a=; while true; do > rc=0; read -N1024 b || rc=$?; a=$a$b; [ $rc = 0 ] || break; done; echo "$a"' > aaa IFS= read -rd '' a printf %s "$a"
Re: bash displays strange characters after base64 decoding
On Thu, Aug 06, 2015 at 07:45:53PM +0200, Valentin Schmidt wrote: > Bash displays strange characters (including command prompt) (see attached > png file) after the execution of the base64 (GNU coreutils 8.21) command > like described as follows: > base64 -d base64.txt Xterm has some escape sequences that switch between a second character set, where many of the ascii letters become line drawing characters instead. Try the following: printf %b '\e(0' {a..z} '\n' '\e(B' {a..z} '\n' This prints the 26 lowercase ascii letters in the second character set, entered by the sequence ESC ( 0, followed by the same line after switching back, with the sequence ESC ( B. In a Gnome Terminal on Ubuntu I get the following output from the above: ▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥ abcdefghijklmnopqrstuvwxyz Sven Mascheck has written a bit about this fun feature here: http://www.in-ulm.de/~mascheck/various/alternate_charset/ -- Geir Hauge
Re: read and env variables + POSIX => SEGFAULT
On Sat, Oct 10, 2015 at 08:01:05PM -0700, Linda Walsh wrote: > # this is odd: 2vars with content for 2: > >unset a b > >a= b= read a b <<< x y > >declare -p a b > declare -- a="x" > declare -- b="" > > # -- where did "y" go? read a b <<< x y is the same as read a b y <<< x If you escape the space, to make it literal instead of syntactical, you'll get the expected result: $ a= b= read a b <<< x\ y $ declare -p a b declare -- a="x" declare -- b="y"
Re: trap DEBUG and $_
On Mon, Oct 12, 2015 at 07:24:00AM +0200, isabella parakiss wrote: > On 10/11/15, Dan Stromberg wrote: > > Is there a way of outputting a datestamp to shell stderr at the _beginning_ > > of the execution of a command, that won't wipe out $_? > > > > I use $_ quite a bit for the last argument to the previous command, > > interactively. And I'd like to datestamp all my commands. Datestamping > > after with $PS1 is easy, but datestamping before is a little harder. > > > > I've tried using: > > > >function preexec { if tty -s; then echo "$(tput smso)cmd started $(date > > +%Y\ %a\ %b\ %d\ %r)$(tput rmso)"; fi; } > >trap preexec DEBUG > > > > ...but as you might suspect, I'm finding that $_ is always "preexec" with > > this enabled. > > > > Any suggestions? > > > > Thanks! > > > trap '__=$_; preexec; : "$__"' DEBUG And since the preexec function ignores its arguments, it can be shortened to: trap 'preexec "$_"' DEBUG -- Geir Hauge
read -a ignores upper- and lowercase flags
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: darwin14.5.0 Compiler: /usr/bin/clang Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='darwin14.5.0' -DCONF_MACHTYPE='x86_64-apple-darwin14.5.0' -DCONF_VENDOR='apple' -DLOCALEDIR='/opt/local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -DMACOSX -I. -I. -I./include -I./lib -I/opt/local/include -pipe -Os -DSSH_SOURCE_BASHRC -arch x86_64 uname output: Darwin MacGeir 14.5.0 Darwin Kernel Version 14.5.0: Tue Sep 1 21:23:09 PDT 2015; root:xnu-2782.50.1~1/RELEASE_X86_64 x86_64 Machine Type: x86_64-apple-darwin14.5.0 Bash Version: 4.3 Patch Level: 42 Release Status: release Description: read -ra var doesn't change the casing of the strings it assigns when var has been declared with -l or -u. read without -a, and mapfile both work as expected. I also tested the latest devel branch to confirm the bug is still present there. Repeat-By: declare -l a b c d a=( HEllO woRLd ) read -r b <<< "HEllO woRLd" read -ra c <<< "HEllO woRLd" mapfile d <<< "HEllO woRLd" declare -p a b c d Output: declare -al a=([0]="hello" [1]="world") declare -l b="hello world" declare -al c=([0]="HEllO" [1]="woRLd") declare -al d=([0]=$'hello world\n') -- Geir Hauge
Re: bash "while do echo" can't function correctly
On Wed, Apr 13, 2016 at 10:01:23AM +0800, 何建军 wrote: > Hi, I use a very simple statement "cat test.txt | while read line; do echo > $line; done", test.txt is very small, no more than 100 lines. but the > execution of the statement paused during process. test.txt is pasted on > http://paste.bradleygill.com/index.php?paste_id=1647399 > desmond.he@xgimi-dev:/studio/desmond.he$ help | head -n 1 GNU bash, version > 4.3.11(1)-release (x86_64-pc-linux-gnu) > desmond.he@xgimi-dev:/studio/desmond.he$ cat /etc/lsb-release > DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty > DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS" Thanks for help~ You didn't quote the expansion of the line variable, so the result of the expansion is first split into words based on the characters in the special IFS variable, then each of those words that contain glob characters (like *, ? , [...]) will be replaced by matching filenames, if any. It's the last part that bites you here, since several of your lines contain * characters. Worse if globstar is enabled, since there's also ** in there, so the "pause" you get is probably bash trying to recurse through the entire filesystem, which may take a while. The fix is easy. Just surround the expansion in double quotes, which prevent word-splitting and pathname expansion. while read -r line; do echo "$line"; done < test.txt though printf should be preferred over echo: while read -r line; do printf '%s\n' "$line"; done < test.txt -- Geir Hauge
Re: -eq and strings
On Mon, Mar 06, 2017 at 03:31:31PM +0100, Rob la Lau wrote: > On 06-03-17 15:16, Reuti wrote: > > if ! expr "$x" : '[[:digit:]]*$' >/dev/null; then echo no; fi > > > > if [ -n "${x//[0-9]/}" ]; then echo no; fi > > True, but regular expressions are usually considered expensive. > (Must admit I never benchmarked.) > > And I know 1 regex won't considerably slow down my script, but it's > become a habit to always try and program as light as possible. If you're counting milliseconds, pattern matching should be slightly faster than your -eq hack. is_digit() { [[ -n $1 && $1 != *[![:digit:]]* ]]; } or the sh variant: is_digit() { case $1 in ''|*[![:digit:]]*) return 1;; esac; } See also http://mywiki.wooledge.org/BashFAQ/054 -- Geir Hauge
Re: Trailing newlines disappear
On Fri, Jun 09, 2017 at 03:34:39AM +0700, PePa wrote: > On 09/06/2560 02:14, Greg Wooledge wrote: > > Well, it leaves IFS changed, because you didn't revert or unset it, > > or run the entire thing in a function with local IFS. Also, I'd use > > "${MAPFILE[*]}" to reinforce that you are joining an array into a string, > > rather than expanding the array as a list. > > Thanks for pointing all this out. I settled on: > mapfile <"$file"; IFS= foo=${MAPFILE[*]} true Greg already pointed out that this doesn't work. You can pick one of these instead: mapfile < "$file"; IFS= foo="${MAPFILE[*]}"; unset -v IFS or mapfile < "$file"; printf -v foo %s "${MAPFILE[@]}" -- Geir Hauge