Re: Feature: where terminal reports mouse click to bash, support positioning the cursor accordingly
On Sun, 17 Jan 2021, mcarans--- via Bug reports for the GNU Bourne Again SHell wrote: Hi, It would be great to be able to use the mouse to click to position the cursor in bash. I raised this with the Gnome terminal emulator here and they said "The cursor position is under the control of the application, not the terminal emulator. vte supports reporting the mouse click to the application, and the application can reposition the cursor accordingly." My request is that bash support the mouse information that terminal emulators pass to it so that it is possible to click the mouse button to position the cursor. https://cfajohnson.com/shell/?2005-07-15_mousetraps -- Chris F.A. Johnson <http://cfajohnson.com/> === Author: === Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux shell (2009, Apress)
Re: Preventing Bash Variable Confusion
On Thu, 30 Jan 2020, Roger wrote: They still allow you to define constants in all-caps. The impact it makes is not so different with defining globals as such. Try Ruby. The reason I used to prefer using all uppercase/capital letters, the variable definitations would stand out similar to C style definition macros. Variables become extremely identifiable and comprehensible. A text editor, such as emacs in Bash mode, can highlight variables. No need to use any sort of naming convention. -- Chris F.A. Johnson <http://cfajohnson.com/> === Author: === Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux shell (2009, Apress)
Re: Preventing Bash Variable Confusion
On Wed, 29 Jan 2020, Chet Ramey wrote: On 1/29/20 2:05 PM, Roger wrote: "Linux Shell Scripting with Bash." (Burtch) suggested using declare instead of local, due to local lacking the other switches declare provides. p262 (eg. declare can specify type of variable, such as integar only.) This is just wrong. `local' accepts the same option set as `declare'. There are other things wrong in that book as well; the description of printf, for example. Don't use it as an authority on bash. -- Chris F.A. Johnson <http://cfajohnson.com/> === Author: === Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux shell (2009, Apress)
Re: Preventing Bash Variable Confusion
On Wed, 29 Jan 2020, Greg Wooledge wrote: As long as you use at least one lowercase letter in your variable name, you are guaranteed not to conflict with any internal shell variables. Except for auto_resume and histchars. -- Chris F.A. Johnson <http://cfajohnson.com/> === Author: === Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux shell (2009, Apress)
Re: man bash does not list 'in' as a builtin command
On Mon, 25 Nov 2019, Peter Benjamin wrote: 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-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib - Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash- N2nMjo/bash-4.4.18=. -fstack-protector-strong -Wformat -Werror=format- security -Wall -Wno-parentheses -Wno-format-security uname output: Linux Precision 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.4 Patch Level: 20 Release Status: release Description: 'in' is a builtin command and is not listed in the man page as such. $ type in in is a shell keyword -- Chris F.A. Johnson <http://cfajohnson.com/> === Author: === Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux shell (2009, Apress)
Re: $"\t': Bash bug or not?
On Sat, 18 Nov 2017, PePa wrote: On 11/15/2017 11:06 PM, Greg Wooledge wrote: On Wed, Nov 15, 2017 at 09:01:52AM -0600, Rick Richardson wrote: tab=$'\t' echo "$tab " | xod Where can I get xod? I don't know about xod, but od is a standard utility, and hd is also commonly installed. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: consistency probs var & function re-use
On Fri, 9 Jun 2017, L A Walsh wrote: Chris F.A. Johnson wrote: On Fri, 9 Jun 2017, L A Walsh wrote: First problem: If you are assigning a string to a variable, you need to put quotes around the string. You don't need to quote it unless it contains literal whitespace. Not exactly true -- "any" type of white space, including newlines, which was the case in Greg's example. A newline IS literal whitespace. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: consistency probs var & function re-use
On Fri, 9 Jun 2017, L A Walsh wrote: Chris F.A. Johnson wrote: On Fri, 9 Jun 2017, L A Walsh wrote: First problem: If you are assigning a string to a variable, you need to put quotes around the string. You don't need to quote it unless it contains literal whitespace. Not exactly true -- "any" type of white space, including newlines, which was the case in Greg's example. A newline IS literal whitespace. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: consistency probs var & function re-use
On Fri, 9 Jun 2017, L A Walsh wrote: First problem: If you are assigning a string to a variable, you need to put quotes around the string. You don't need to quote it unless it contains literal whitespace. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: weird error due to cntrl-c out of history list
On Sun, 19 Feb 2017, L A Walsh wrote: In both 4.3.42(2)-release and 4.4.5(1)-release, I was listing my history (history cmd) and hit control-C and got: 4402 0502@091824: ls * 4403 0502@091901: cd .. 4404 0502@091930: cd xyzzy-1.8.4.1/ 4405 0502@091932: ls 4406 0502@091939: grep -r template . ^C bash: printf: write error: Success I usually get no messsage, or occasionally: 43708 30-Sep-2016_21:33:41 jfr2html-sh 43709 30-Sep-2016_21:33:54 u books 43710 01-Oct-2016_15:17:54 jfr 43711 01-Oct-2016_21:38:05 kjgrep Deuteronomy~023 ^Cbash: printf: write error: Interrupted system call -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: 'cat' and 'rm' as builtins ?
On Sun, 30 Oct 2016, Tim Rühsen wrote: ... Since cat and rm implementations are pretty small in code size, I wonder if you (the maintainers) would accept patches to make these commands builtin commands. Have you looked at the loadable builtins in the examples directory? -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: Bash-4.4-beta2 available for download
On Wed, 13 Jul 2016, Chet Ramey wrote: On 7/13/16 10:58 AM, Chet Ramey wrote: On 7/13/16 10:49 AM, Chris F.A. Johnson wrote: On Tue, 12 Jul 2016, Chet Ramey wrote: The second beta release of bash-4.4 is now available with the URL ftp://ftp.cwru.edu/pub/bash/bash-4.4-beta2.tar.gz I get nothing. wget just hangs: It looks like a problem with the AWS load balancer. For now, get it from ftp.gnu.org. I was able to retrieve a copy from ftp.cwru.edu using wget (passive mode) and an ftp client (extended passive mode). Try it again and let me know the results. It worked this time. Thanks. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: Bash-4.4-beta2 available for download
On Tue, 12 Jul 2016, Chet Ramey wrote: The second beta release of bash-4.4 is now available with the URL ftp://ftp.cwru.edu/pub/bash/bash-4.4-beta2.tar.gz I get nothing. wget just hangs: $ wget ftp://ftp.cwru.edu/pub/bash/bash-4.4-beta2.tar.gz --2016-07-13 10:46:45-- ftp://ftp.cwru.edu/pub/bash/bash-4.4-beta2.tar.gz => 'bash-4.4-beta2.tar.gz' Resolving ftp.cwru.edu (ftp.cwru.edu)... 50.17.163.19, 52.87.62.244 Connecting to ftp.cwru.edu (ftp.cwru.edu)|50.17.163.19|:21... connected. Logging in as anonymous ... Logged in! ==> SYST ... done.==> PWD ... done. ==> TYPE I ... done. ==> CWD (1) /pub/bash ... done. ==> SIZE bash-4.4-beta2.tar.gz ... 8932859 ==> PASV ... -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: Bash logo
On Wed, 16 Dec 2015, Chet Ramey wrote: For many years, my bash page (tiswww.case.edu/~chet/bash/bashtop.html) has sported a bash logo that someone whose name I have lost donated long ago. I received a very generous offer to create a new logo and donate it for the project's use. The benefactor is Justin Dorfman, and he has been very patient to wait for me to select from among a number of good alternatives (part of what made it so tough). We have narrowed the field to three proposed designs, and it is time for the bash community to decide on the winner. There is a Google form with the proposed new logo designs where you can vote for your favorite: http://goo.gl/forms/qjohwvtgys I chose no. 2, but I would like it better with the colours reversed. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: why must bash zap last search string just because we hit ^C?
On Sun, 18 Oct 2015, 積丹尼 Dan Jacobson wrote: DW> On Fri, Oct 16, 2015 at 1:50 PM, Chet Ramey <chet.ra...@case.edu> wrote: DW> ^C rudely aborts the entire operation. Why assume you want to save any DW> of the context? Because I got a phone call: the boss asked me to execute a shell command. I used ^C to get myself back to a prompt so I could type in the command. Now I want to resume searching and must type my ^Rlong_search_string all over again. OK I suppose I can train myself to do ^A # RET or ESC ESC # instead. Or just press UP (as many times as necessary) and RET. -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: why must bash zap last search string just because we hit ^C?
On Sun, 18 Oct 2015, 積丹尼 Dan Jacobson wrote: "CFAJ" == Chris F A Johnson <ch...@cfajohnson.com> writes: CFAJ> Or just press UP (as many times as necessary) and RET. That won't get me to a $ prompt. I want to suspend my search and resume it later. ^Z then fg -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: Design question(s), re: why use of tmp-files or named-pipes(/dev/fd/N) instead of plain pipes?
On Sat, 17 Oct 2015, Linda Walsh wrote: Chet Ramey wrote: On 10/16/15 7:52 PM, Linda Walsh wrote: As I mentioned, my initial take on implementation was using standard pipes instead of named pipes (not having read or perhaps having glossed over the 'named pipes' aspect). I think you're missing that process substitution is a word expansion that is defined to expand to a filename. When it uses /dev/fd, it uses pipes and exposes that pipe to the process as a filename in /dev/fd. Named pipes are an alternative for systems that don't support /dev/fd. - ??? I've never seen a usage where it expands to a filename and is treated as such. Try this: echo <(cat /etc/passwd) -- Chris F.A. Johnson, <http://cfajohnson.com>
Re: coredump with wait -n
On Sat, 22 Aug 2015, isabella parakiss wrote: Hi, after running wait -n there's something wrong, ^C doesn't work properly anymore: it displays ^C in the readline buffer, but the current line stays there until I press enter. Running any command fixes it. It can also dump core if you try with multiple jobs. $ bash --norc bash-4.3$ sleep 1 sleep 2 wait -n [1] 8368 [2] 8369 [1]- Donesleep 1 bash-4.3$ ^C*** stack smashing detected ***: bash terminated I have no problem running that line, and ^C still works. -- Chris F.A. Johnson, http://cfajohnson.com
Re: No support for spaces in for loop
On Wed, 19 Aug 2015, Yan Pashkovsky wrote: 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-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wall uname output: Linux mint-desktop 3.16.0-43-generic #58~14.04.1-Ubuntu SMP Mon Jun 22 10:21:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.3 Patch Level: 11 Release Status: release Description: for file in * doesn't correctly parse files containing spaces in their filenames. For example file an image of duck.jpg will be interpreted as 4 files an image of duck.jpg Yes, it does. Your problem is (probably, since you didn't include an example) that you omitted quotes around its expansion, e.g.: printf '%s\n' $file That should be: printf '%s\n' $file Repeat-By: -- Chris F.A. Johnson, http://cfajohnson.com
Re: BUG?: (or what's going on?) test for NL == NL fails (bash-4.3.39(3)-release)
On Sun, 2 Aug 2015, Linda Walsh wrote: also noticed this similar strange behavior: used 'ord'** for this test (trying to compare decimal val of chars) isatty () { test -c /proc/self/fd/1 ; } ord () { local nl=; isatty nl=\n; printf %d$nl '$1 ; } ord () { local nl=; isatty nl=\n; printf %d$nl '$1 ; } ord $(printf \n) Trailing newline are stripped from command substitution, making $(printf \n) and empty string. If you want a newline, use: ord $'\n' -- Chris F.A. Johnson, http://cfajohnson.com
Re: Problem with brace expansion
On Tue, 21 Apr 2015, Dr Alun J. Carr wrote: There appears to be a bug in bash when using a variable in curly brace expansion, e.g., {1..$n}. I have put the two following test scripts in the attached files looper1.sh and looper2.sh: Brace expansion is done before variable expansion: The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion. Neither pdksh (which installs as ksh using homebrew) nor dash handle either case correctly: Neither pdksh nor dash has brace expansion. -- Chris F.A. Johnson, http://cfajohnson.com
Re: Should nested case statements within command substitutions work on in bash 3.2.x?
On Sun, 22 Mar 2015, Jon Seymour wrote: I was surprised that this didn't work with the OSX version of bash 3.2: /bin/bash -c 'echo $(case yes in yes) echo yes; ;; no) echo no; ;; esac)' /bin/bash: -c: line 0: syntax error near unexpected token `;;' /bin/bash: -c: line 0: `echo $(case yes in yes) echo yes; ;; no) echo no; ;; esac)' It does work with bash 4.x. Is this a known issue with 3.2 or is it particular to the OSX implementation (which in my case is 3.2.53(1))? Balance the parentheses: echo $(case yes in (yes) echo yes; ;; (no) echo no; ;; esac) -- Chris F.A. Johnson, http://cfajohnson.com
Re: Bash-4.3 Official Patch 25
On Wed, 24 Sep 2014, m...@ibiblio.org wrote: Bash-Release:4.3 Patch-ID:bash43-025 As a binary distribution archive maintainer, I'd be keen to see the authors distributing a cumulative bash-4.3p025.tar.gz source bundle (probably p026 to nail the new issues above). The ftp://ftp.cwru.edu/pub/bash site just has the main 4.3 file and 25 separate patches to merge. A downloadable tar file of the current version with all official patches applied is available from savannah. http://git.savannah.gnu.org/cgit/bash.git/snapshot/bash-master.tar.gz -- Chris F.A. Johnson, http://cfajohnson.com
Re: Substring Expansion does not work as intended
On Wed, 20 Aug 2014, Eric Blake wrote: On 08/20/2014 07:05 AM, eckard.bra...@gmx.de wrote: Not a bug. Description: Substring Expansion actually works different than manpage states, namely: If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter. Read further. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the :- expansion. Repeat-By: x=abcdef; echo ${x:-2} Expected: ef Got: abcdef echo ${x: -2} Or use a variable: o=-2 echo ${x:$o} -- Chris F.A. Johnson, http://cfajohnson.com
Re: read-only flag is lost for functions in sub shells
On Thu, 31 Jul 2014, Chet Ramey wrote: On 7/31/14, 10:51 AM, Linda Walsh wrote: ... I thought the idea of RO vars being passed to children was considered desirable? As Greg says, there's no existing mechanism to do that using the environment, which is the only way to communicate across exec(2). I could invent something, but what would be the point? It's not hard to do, e.g. as a comma-separated list of readonly variables: export READONLY_VARS=foo,bar,why,not foo bar why not In the receiving script: if [[ -n $READONLY_VARS ]] then IFS=, read -a rov $READONLY_VARS readonly ${rov[@]} fi foo=q ## not permitted -- Chris F.A. Johnson, http://cfajohnson.com
Re: umask --help
On Mon, 7 Jul 2014, Notes Jonny wrote: ... Would you consider adding a --help option for umask please? (I understand this is a built in command) Maybe also --version I was just hoping to find some help for it. info umask and man umask also don't say anything. help umask
Re: odd behavior from overloading the source builtin
On Sun, 16 Mar 2014, Doug McIlroy wrote: GNU bash, version 4.2.39(1)-release (x86_64-redhat-linux-gnu) interprets this shell script differently when bash input comes from a terminal or when it conmes from a file: source(){ echo x } source In the former case it prints x; in the latter it gives a missing-filename diagnostic, presumably from the builtin source. The behavior is independent of whether the environment contains source(). The bash man page leads me to expect the former behavior because commands are said to be looked up first among shell functions, then among builtins. The behavior seems to be peculiar to source. If source is replaced by wait, the difference vanishes. I get the same behaviour whether entered in a terminal or executed in a script (bash 4.2 and 4.3). $ source(){ echo x } $ source x $ xx.sh x
Re: continuously evaluated prompts/environmental variables
On Mon, 25 Nov 2013, Edward Peschko wrote: All, I was wondering if there was a way to make an environmental variable be evaluated each time it was accessed. In other words, with: export PS1=`whoami`@`hostname` This works for the first time that the prompt is evaluated, what I would like to have is a prompt to be continuously evaluated, so that if whoami or hostname changes, the prompt changes along with it. Is there a way to have the prompt - or any other environmental variable - change in this way, based off external command? Use single quotes: PS1='`whoami`@`hostname`' -- Chris F.A. Johnson, http://cfajohnson.com
Re: How to create bash-pattern to exclude a matching param in param expansionmatching?
On Mon, 28 Oct 2013, Linda Walsh wrote: I am missing how to create a bash-pattern that excludes a specific pattern. I.e. to ignore any file with '-IGN-' somewhere in the filename. The best I've come up with so far has been to use shell to build a pattern, but I know it is limited in functionality. I.e.: ls !($(echo *+(-IGN-)*|tr |)) I tried the above in a dir that has 2 files w/the pattern, and 532 w/o, and it worked, but how much of that was 'luck'? Is there a better bash-pattern that doesn't use tr and such? ls !(*-IGN-*) -- Chris F.A. Johnson, http://cfajohnson.com/
Re: i++ cause bad return code when result is 1
On Tue, 27 Aug 2013, Chris Down wrote: On 2013-08-26 21:36, David Lehmann wrote: My issue is that the resulting behavior in Exercise 1 does not make sense. The resulting value of i should have no bearing on the exit code. If the addition succeeded, the expression should return 0 (success). If i was not an integer (e.g. i=hello), then I expect (( i++ )) to return a non-zero error code. ...IMHO, of course. That would be pretty much rewriting the entire way that (( works, since the whole point is that it returns a status based upon having a return value that is 0. Rather, that it is != 0 Compare: $ (( 0 )); echo $? 1 $ (( 1 )); echo $? 0 $ (( -1 )); echo $? 0 -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: ldapscripts unusable from within a 'while read line' loop
On Thu, 1 Aug 2013, Lakshminarasimhan Srinivasan wrote: ... Description: ldapscripts do not work from inside a while read line loop. The exact same scripts were working fine until the last upgrade Repeat-By: Prerequisite: ldapscripts installed. Open a new bash script and type in the following: - #!/bin/bash echo Testing if it works outside of the loop ldapid echo Getting into the read line loop while read line do ldapid done Some file The 'ldapid' command, which works outside of the loop, does not work from within. This time it throws an error Cannot guess user. Now we check an alternative: Create a new script and type in the following: #!/bin/bash echo Testing if it works outside of the loop ldapid readarray lines some file echo Getting into the for loop for line in ${lines[@]} do ldapid done --- In this case 'ldapid' works both times. In fact, ldapid works in every other loop except a 'while read line' and I really do not have any idea why. I have no idea what ldapid is or does (I can't find it for my system), but perhaps it reads from stdin? If it does, it will be reading from the file. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: corrupted input after size function (input that's not recorded by bash)
On Thu, 13 Jun 2013, Linda Walsh wrote: I have a small function in my bashrc: function showsize () {\ local s=$(stty size); local o=(${s% *}x${s#* }); s=${#o};\ echo -n $o; while ((s-- 0));do echo -ne \b; done; \ } export -f showsize trap showsize SIGWINCH --- That has the effect of showing me my current window size when I resize it. The odd thing is, if I use it while at a bash input prompt -- any command I type has the first word ignored. so if I type: echo cmd If 'cmd' is not a typo you can use command-not-found to lookup the package that contains it, like this: cnf cmd --- But then I re-edit the line (in vi-mode, ESC-k, it shows me I typed echo cmd -- and, indeed, if I hit return, it echo's the word 'cmd' w/no error. So how can my showsize function be mangling the input in a way that prevents proper execution, but isn't recorded by bash? (this has been one of those things that's bothered me for years, but never been important enough to even ask about... I thought I'd look at it to fix it, but still don't see why it does what it does). Any clues? The baskspaces (\b) are erasing your input, not the function's output. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: currently doable? Indirect notation used w/a hash
On Mon, 10 Jun 2013, Greg Wooledge wrote: On Sun, Jun 09, 2013 at 02:02:02PM -0700, Linda Walsh wrote: I was wondering if I was missing some syntax somewhere... but I wanted to be able to pass the name of a hash in and store stuff in it and later retrieve it... but it looks like it's only possible with an eval or such? Passing arrays by reference (by name) to a function will be possible in bash 4.3. It is not possible in current versions of bash, without using eval trickery, as you have already noted. And doing it with eval is so difficult that it's easier to switch languages entirely. It is not the least bit difficult with eval: eval array=( \\${$1[@]}\ ) -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: currently doable? Indirect notation used w/a hash
On Mon, 10 Jun 2013, Chris Down wrote: Enjoy your arbitrary command execution. Can you give me an example, using the code I posted, where that would happen? On 10 Jun 2013 14:15, Chris F.A. Johnson ch...@cfajohnson.com wrote: On Mon, 10 Jun 2013, Greg Wooledge wrote: On Sun, Jun 09, 2013 at 02:02:02PM -0700, Linda Walsh wrote: I was wondering if I was missing some syntax somewhere... but I wanted to be able to pass the name of a hash in and store stuff in it and later retrieve it... but it looks like it's only possible with an eval or such? Passing arrays by reference (by name) to a function will be possible in bash 4.3. It is not possible in current versions of bash, without using eval trickery, as you have already noted. And doing it with eval is so difficult that it's easier to switch languages entirely. It is not the least bit difficult with eval: eval array=( \\${$1[@]}\ ) -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: currently doable? Indirect notation used w/a hash
On Mon, 10 Jun 2013, Greg Wooledge wrote: On 10 Jun 2013 14:15, Chris F.A. Johnson ch...@cfajohnson.com wrote: It is not the least bit difficult with eval: eval array=( \\${$1[@]}\ ) On Mon, Jun 10, 2013 at 09:17:23PM +0800, Chris Down wrote: Enjoy your arbitrary command execution. To be fair, Chris Johnson was probably assuming a programming environment where the function is only callable from within the same script, and thus has only trustworthy arguments provided by the caller. Sometimes, this is the case. Sometimes, it isn't. The example I gave is always safe; it expands, given 'q' as the argument, to: array=( ${q[@]} ) What's unsafe about that? Why would it need any preprocessing? -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: currently doable? Indirect notation used w/a hash
On Mon, 10 Jun 2013, Greg Wooledge wrote: On Mon, Jun 10, 2013 at 10:23:10AM -0400, Chris F.A. Johnson wrote: On Mon, 10 Jun 2013, Chris Down wrote: Enjoy your arbitrary command execution. Can you give me an example, using the code I posted, where that would happen? On 10 Jun 2013 14:15, Chris F.A. Johnson ch...@cfajohnson.com wrote: eval array=( \\${$1[@]}\ ) imadev:~$ foobar() { set -x; eval array=( \\${$1[@]}\ ); } imadev:~$ foobar 'a}); date; b=(${q' + foobar 'a}); date; b=(${q' + set -x + eval 'array=( ${a}); date; b=(${q[@]} )' ++ array=(${a}) ++ date Mon Jun 10 10:31:41 EDT 2013 ++ b=(${q[@]}) A really clever attack wouldn't leave those extra variables lying around, either. I stopped at working and didn't spend the extra time for clever. Point taken, but the only way such a string would be passed as a variable name is if it was given as user input -- which would, presumably, be sanitized before being used. Programming it literally makes as much sense as 'rm -rf /'. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: `declare -fp` mishandles heredoc with || statement
On Fri, 31 May 2013, Mike Frysinger wrote: simple code snippet: $ cat test.sh func() { cat / EOF || echo FAIL 11 EOF } declare -fp when run, we see the || statement is incorrectly moved to after the heredoc: $ bash ./test.sh func () { cat / EOF 11 EOF || echo FAIL } every version of bash i tried fails this way (2.05b through 4.2.45) With 4.2.37: func () { cat / EOF || 11 EOF echo FAIL } -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Interpretation of escapes in expansions in pattern matching contexts
On Sat, 6 Apr 2013, Chet Ramey wrote: On 4/6/13 4:48 AM, Dan Douglas wrote: I couldn't find anything obvious in POSIX that implies which interpretation is correct. Assuming it's unspecified. Bash (4.2.45) uniquely does interpret such escapes for [[, which makes me think this test should say no: x=\\x; if [[ x == $x ]]; then echo yes; else echo no; fi bash: yes ksh: no mksh: no zsh: no However, ksh93 (AJM 93v- 2013-03-17) is unique in that it flips the result depending on [[ ]] or case..esac (bug?), but otherwise it looks like a fairly random spread: x=\\x; case x in $x) echo yes;; *) echo no; esac These two cases should not be different. They undergo the same expansions, except that the conditional command adds quote removal, which doesn't matter in this case. In both cases, you ask the pattern matching code whether or not the string `x' matches the pattern `\x'. You invoke the same pattern matching code on the same patterns, why would you not get the same answer? In bash, the expansion differs when in [[ ... ]]: $ x=\\x; if [[ x == $x ]]; then echo yes; else echo no; fi yes $ x=\\x; if [ x == $x ]; then echo yes; else echo no; fi no But not in ksh93: $ x=\\x; if [[ x == $x ]]; then echo yes; else echo no; fi no $ x=\\x; if [ x == $x ]; then echo yes; else echo no; fi no -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Local variables overriding global constants
On Wed, 3 Apr 2013, Nikolai Kondrashov wrote: Hi everyone, It seems Bash 4.2.37 doesn't allow functions to redefine global constants locally, yet it allows redefining constants local to calling functions. Is this as supposed to be, or is it a bug? I.e. this: bash -c 'declare -r v; a() { declare -r v; }; a' Results in: bash: line 0: declare: v: readonly variable It doesn't work because you are trying to redefine an existing readonly variable. While this works: bash -c 'a() { declare -r v; }; b() { declare -r v; a; }; b' It works because both instances are local to a function and don't exist outside their own functions. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Local variables overriding global constants
On Wed, 3 Apr 2013, Nikolai Kondrashov wrote: On 04/03/2013 10:53 AM, Chris Down wrote: On 2013-04-03 10:50, Nikolai Kondrashov wrote: On 04/03/2013 10:43 AM, Chris F.A. Johnson wrote: On Wed, 3 Apr 2013, Nikolai Kondrashov wrote: I.e. this: bash -c 'declare -r v; a() { declare -r v; }; a' Results in: bash: line 0: declare: v: readonly variable It doesn't work because you are trying to redefine an existing readonly variable. Yes, but I'm explicitly redefining it locally, only for this function. And this works for variables previously defined in the calling function. You're not redefining it locally, you are unsuccessfully trying to override a global. How is this different? bash -c 'declare v=1; function a() { declare v=2; }; a; echo $v' In a() you created a new, local variable, which you could do in this instance because it is not readonly. While this works: bash -c 'a() { declare -r v; }; b() { declare -r v; a; }; b' It works because both instances are local to a function and don't exist outside their own functions. Not true. This: bash -c 'a() { echo $v; }; b() { declare -r v=123; a; }; b' Produces this: 123 That is *inside* the function, not *outside* the function. I'd say that v is declared outside function a, where it is accessed, or do you mean that there is no concept of separate functions in Bash and all functions are just one function? a() is a child of b(), so it can see its variables. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Local variables overriding global constants
On Wed, 3 Apr 2013, Pierre Gaston wrote: On Wed, Apr 3, 2013 at 11:03 AM, Chris Down ch...@chrisdown.name wrote: On 2013-04-03 11:00, Nikolai Kondrashov wrote: It doesn't work because you are trying to redefine an existing readonly variable. Yes, but I'm explicitly redefining it locally, only for this function. And this works for variables previously defined in the calling function. You're not redefining it locally, you are unsuccessfully trying to override a global. Still Nikolai has a point. It's not clear why readonly variable can be overridden when the variable is declared readonly in the scope of an englobing function but not if it is declared readonly in the global scope. If it's declared readonly in a function, the variable doesn't exist outside of that function, so it's not readonly there. $ bash -c 'a() { v=2;echo $v; }; b () { declare -r v=1; a; echo $v; }; b' bash: v: readonly variable The variable is locale to b, but the readonly flag is preserved in a $ bash -c 'a() { declare -r v=2;echo $v; }; b () { declare -r v=1; a; echo $v; }; b' 2 1 The variable is locale to b, but you can redeclare it locale to a even if it has the readonly flag $ bash -c 'declare -r v=2; b () { declare -r v=1; echo $v; }; b' bash: line 0: declare: v: readonly variable 2 it looks like the same as the first case except that the variable is declared readonly in the global scope. (Also readonly defers from declare -r: bash -c 'a() { declare -r v=2;echo $v; }; b () { readonly v=1; a; echo $v; }; b; v=2' $ bash -c 'a() { declare -r v=2;echo $v; }; b () { readonly v=1; a; echo $v; }; b; v=2' bash: line 0: declare: v: readonly variable 1 1 bash: v: readonly variable. I seem to recall this has been discussed on this list at some point) -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Local variables overriding global constants
On Wed, 3 Apr 2013, Pierre Gaston wrote: On Wed, Apr 3, 2013 at 11:33 AM, Chris F.A. Johnson ch...@cfajohnson.comwrote: On Wed, 3 Apr 2013, Pierre Gaston wrote: On Wed, Apr 3, 2013 at 11:03 AM, Chris Down ch...@chrisdown.name wrote: On 2013-04-03 11:00, Nikolai Kondrashov wrote: It doesn't work because you are trying to redefine an existing readonly variable. Yes, but I'm explicitly redefining it locally, only for this function. And this works for variables previously defined in the calling function. You're not redefining it locally, you are unsuccessfully trying to override a global. Still Nikolai has a point. It's not clear why readonly variable can be overridden when the variable is declared readonly in the scope of an englobing function but not if it is declared readonly in the global scope. If it's declared readonly in a function, the variable doesn't exist outside of that function, so it's not readonly there. I think you missed the point that a is called inside b. See the example below $ bash -c 'a() { v=2;echo $v; }; b () { declare -r v=1; a; echo $v; }; b' bash: v: readonly variable if v doesn't exist in a why does it complain that it's readonly? It *does* exist inside a() if a() is a child of b(). -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Bug/limitation in 'time'
On Sun, 17 Mar 2013, William Park wrote: On Sat, Mar 16, 2013 at 10:15:50PM -0400, Chris F.A. Johnson wrote: On Sun, 17 Mar 2013, Chris Down wrote: ExprCount() { for (( i = $1 ; i 0 ; i-- )); do : done echo $1 iterations } Or, in a POSIX-compliant manner: ExprCount() { i=$1 while [ $(( i -= 1 )) -ge 0 ]; do : done echo Just did $1 iterations using expr math } Are you saying that for (( ; ; )) is not POSIX? Right. But $(( ... )) is POSIX. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: More fun with IFS
On Wed, 30 Jan 2013, Andreas Schwab wrote: Chris F.A. Johnson ch...@cfajohnson.com writes: var=${a[*]} ... one two three four # bad Looks good to me. It expands to multiple words, just as an unquoted $* would do. But no field splitting is performed on the expansion, so why are the colons lost? How is it printed if it is not expanded? The expansion is done when it is printed. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: More fun with IFS
On Wed, 30 Jan 2013, Dan Douglas wrote: Hi everyone, and welcome to another edition of IBOTD (IFS-bug-of-the-day), featuring everyone's favorite Bourne shell kludge: word-splitting! On today's episode - inconsistencies within assignments that depend upon quoting. Though I can't take credit for discovering this -- it was pointed out to me by some guys on IRC after demonstrating some other stuff. And a quick test: function expassign { typeset -a a a=($@) typeset var asn while IFS= read -r asn; do IFS=: command eval $asn printf '%-14s... %s\n' $asn $var done \EOF var=${a[*]} var=${a[*]} var=$* var=$* var=${a[@]} var=${a[@]} var=$@ var=$@ EOF } ${ZSH_VERSION+:} false emulate ksh expassign one:::two three:::four Bash output: # I think... var=${a[*]} ... one two three four # bad Looks good to me. It expands to multiple words, just as an unquoted $* would do. var=${a[*]} ... one:::two:three:::four # good var=$*... one:::two:three:::four # good var=$* ... one:::two:three:::four # good var=${a[@]} ... one two three four # bad As above. var=${a[@]} ... one:::two three:::four # good var=$@... one two three four # bad Ditto. var=$@ ... one:::two three:::four # good Zsh and pdkshes produce: one:::two:three:::four For all of the above, which I think is wrong for the last 4. ksh93 produces: one:::two three:::four for the last 4, which I think is correct. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: fd leak with {fd}
On Mon, 26 Nov 2012, Chet Ramey wrote: ,,, There have been unsuccessful new features -- the case-modifying expansions are one example of a swing and miss. A miss? I use them a lot. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
RFE: read -d STRING
I would find it very useful to allow a string of delimiters to be used with 'read -d', with any member of the string terminating the input and the character used being stored in a variable, e.g. READ_DELIM. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Parsing error when case in for in $()
On Tue, 11 Sep 2012, Benoit Vaugon wrote: ... Description: Cannot use case construction in a for loop in a $() sub shell. Should work but produces parsing error. Repeat-By: echo $(for x in whatever; do case y in *) echo 42;; esac; done) The closing parentheses in the case statement is being interpreted as the closing for $( Fix: Probably by fixing the bash parser. Balance the parentheses in the case statement: echo $(for x in whatever; do case y in (*) echo 42;; esac; done) -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Double quoted history expansion character cannot be escaped
On Mon, 6 Aug 2012, ksi...@gmail.com wrote: According to the bash man page, it appears that only backslash and single quotes can escape the history expansion character ('!' by default). However, bash refuses to escape the history expansion character when placed in double quotes DESPITE acting as if it had actually done so. ... This is simply perverse and should be fixed as there doesn't seem to be any reason for this behavior. I find it perverse that a printing character does anything other than print itself on the screen. To fix that, I put this in ~/.bashrc: histchars= -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: why must non-standard $IFS members be treated so differently ?
On Sun, 29 Jul 2012, Jason Vas Dias wrote: Good day Chet, list - I'm concerned about the difference in output of these functions with the example input given on the '$' prefixed line below (with 4.2.29(2)-release (x86_64-unknown-linux-gnu)): function count_args {v=($@); echo ${#v[@]}; } Always quote $@. Without quotes, it's the same as $* function count_args {v=( $@ ); echo ${#v[@]}; } -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: locale specific ordering in EN_US -- why is aAbByYzZ?
On Mon, 21 May 2012, Linda Walsh wrote: Greg Wooledge wrote: On Sun, May 20, 2012 at 11:36:35AM -0700, Linda Walsh wrote: For instance, on HP-UX 10.20, in the en_US.iso88591 locale: A a ... B b Meanwhile, on Debian 6.0, in the en_US.iso88591 locale: a A ... b B As you can see, the two en_US.iso88591 implementations are not the same. Great!... So which is correct? Anyone wanting to reference an upper or lower case range [a-z] or [A-Z], is gonna hurt from this. Use the correct references: [:upper:] and [:lower:] or (as I do) always use LC_ALL=C in your scripts. My OS uses en_US.UTF-8. My OS uses whatever I tell it to (which is C). You'd think unicode would have something to say about collation order that wouldn't allow such randomness, but maybe not. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: status on $[arith] for eval arith vsl $((arith))??
On Sat, 7 Apr 2012, Linda Walsh wrote: In modifying some released code on my distro,I ran into the extensive use of $[arith] as a means for returning arithmetic evaluations of the expression. I vaguely remember something like that from years ago, but never see any reference to it -- yet it works, and old code seems to rely on it -- and $[(1+2)/3] looks cleaner than $(((1+2)/3)). So what's up with that? At the minor expense of a few extra keystrokes, $(( (1+2) / 3 )) looks just as clean, and has the added cachet of being portable. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: test if shell is interactive
On Sun, 22 Jan 2012, tapczan wrote: Bob Proulx wrote: Shell scripts are not interactive. So what you are seeing above is correct. So, is there any way to test if script (a.sh) was invoked from interactive session (human) or not (e.g. from cron)? Test whether it is attached to a tty: if [ -t 1 ] then echo Interactive else echo Not interactive fi -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: bash 3.2 vs 3.0
On Thu, 5 Jan 2012, Dave wrote: Hi all, Recently upgraded to 3.2 and noticed some differences in a lot of my scripts, consider the following example: ... Could anyone point me in correct direction on this one ? Upgrade to 4.2; you are years behind the times! -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: converting array to string by quoting each element for eval
On Tue, 15 Nov 2011, Peng Yu wrote: Why not use the array instead of making it into a single string? $cmd ${args[@]} Why are you using eval or quotearg.sh? It sounds as if you are making the process more complicated than it need be. For the examples that I gave, probably it is not necessary. I'm yet to make a concrete complex example to demonstrate its usefulness in practice. But I think that it is easy to imagine that there will be some complex commands that are composed by concatenating multiple strings to be evaled, in which case this may be useful. It may be possible to come up with something, but I doubt that there are many cases where the direct use of an array is not more appropriate (unless you need portability, in which case you wouldn't be using arrays in the first place). In any case, combining a command and its arguments in a single string is almost always the wrong way to go about it. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: converting array to string by quoting each element for eval
On Tue, 15 Nov 2011, Peng Yu wrote: In any case, combining a command and its arguments in a single string is almost always the wrong way to go about it. Please compare the two scripts and see if the second one makes more sense. /tmp$ cat not_convert_args_to_string.sh #!/bin/bash options=$2 find $1 $options echo find $1 $options More sensible would be to have each option a separate argument and do: location=$1 shift find $location $@ /tmp$ cat convert_args_to_string.sh #!/bin/bash options=$2 cmd=find $1 $options eval $cmd echo $cmd See above. /tmp$ ./not_convert_args_to_string.sh . -type f -name '*' find: `./cvcd': Permission denied find . -type f -name '*' Use 'set -x' to see exactly what your script is doing. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Questions about commandline-args
On Fri, 11 Nov 2011, Christopher Roy Bratusek wrote: Hi list, I've got a question about commandline args, imagine: personal_function ab{c,d} personal_function will receive abc and abd. Is there a way to make it receive ab{c,d} instead (without chaning the arguement itself)? Quote it: personal_function ab{c,d} -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Questions about commandline-args
On Sat, 12 Nov 2011, Christopher Roy Bratusek wrote: On Friday 11 November 2011 19:32:51 Chris F.A. Johnson wrote: On Fri, 11 Nov 2011, Christopher Roy Bratusek wrote: Hi list, I've got a question about commandline args, imagine: personal_function ab{c,d} personal_function will receive abc and abd. Is there a way to make it receive ab{c,d} instead (without chaning the arguement itself)? Quote it: personal_function ab{c,d} Hmm.. right. But is there a way to achieve that without quoting? If it is not quoted, the shell will expand it before your script even sees it. Maybe some trap (just like for do X before bash exists)? If you are calling a function, bash already exists. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: invoke tilde expansion on quoted string
On Fri, 11 Nov 2011, Peng Yu wrote: I know from the document that tilde expansion only works if the string is unquoted (see below) ~$ cd '~/..' -bash: cd: ~/..: No such file or directory ~$ cd ~/.. /Users$ 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 -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: bash-completion between do and done
On Sat, 5 Nov 2011, Bob Proulx wrote: Peng Yu wrote: Current, bash doesn't do command completion between do and done (for loop). I'm wondering if this feature can be added. Of course bash does do command completion between do and done. Can you give an exact example test case? On what version of bash? I can confirm it on 3.05b, 3.0 and 4.2: while [ ${n:=0} -lt 5 ] do seTAB All I get is a beep. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Another mapfile question.
On Fri, 5 Aug 2011, Steven W. Orr wrote: One trick that bit me a while back, is that the order of declaring IFS and old_IFS is important. It has to be done in this order: foo() { typeset -r old_IFS=$IFS # Must come first typeset IFS stuff... } I always use local and don't change it back within a function: foo() { local IFS=bar : whatever } The original value is not changed in the calling script. -- Chris F.A. Johnson http://cfaj.freeshell.org === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: awk or sed
On Wed, 6 Apr 2011, ali hagigat wrote: I have a variable like this: var1=Makefile .xcompile /root/build/.config src/arch/i386/Makefile.inc means some words separated by spaces. I want to print each word on a separate line. I think I have to use awk or sed string processing tools. I wonder if anybody have experience with them or any other means to do it. printf %s\n $var1 (You might want to precede that with 'set -f'.) -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: BASH_SUBSHELL documentation misleading
On Wed, 23 Mar 2011, Sam Liddicott wrote: 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/share/locale' -DP$ uname output: Linux sojo 2.6.35-28-generic-pae #49-Ubuntu SMP Tue Mar 1 14:58:06 UTC 2011 i686 GNU/Linux Machine Type: i686-pc-linux-gnu Bash Version: 4.1 Patch Level: 5 Release Status: release Description: man page says: BASH_SUBSHELL Incremented by one each time a subshell or subshell environment is spawned. The initial value is 0. This suggests that: echo $BASH_SUBSHELL ; ( echo ) ; echo $BASH_SUBSHELL would not give the same answer for BASH_SUBSHELL No, it suggests that: echo $BASH_SUBSHELL ; ( echo $BASH_SUBSHELL ) would not give the same answer for BASH_SUBSHELL In your example, the second echo $BASH_SUBSHELL is at the same depth as the first. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Negative array subscript with unset
I all versions I have tried, unsetting an array element using a negative index fails: $ array=( q w e r t y ) $ unset 'array[-1]' bash: [-1]: bad array subscript -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: case modification won't work with pattern
On Thu, 10 Mar 2011, Chet Ramey wrote: On 3/10/11 9:04 PM, Clark J. Wang wrote: On Thu, Mar 10, 2011 at 9:31 PM, Greg Wooledge wool...@eeg.ccf.org wrote: On Thu, Mar 10, 2011 at 10:22:12AM +0800, Jerry Wang wrote: var=abcabc echo var: ${var} echo replace the leading \ab\ to uppercase: ${var^ab} # expect to get ABcabc ? The documentation is a bit terse, admittedly. Agree. Almost all of the poeple around me don't understand why it works that way. Maybe some background of the feature requirement can help us to understand better. The original requests were for a way to change the first letter or every letter to uppercase or lowercase, like ksh typeset -l/-u, using word expansion syntax (one request was for a new builtin command to do it). That's what you get if you don't use the pattern part of the expansion. I invented the pattern following the case specifier to allow each character to be separately modified. I suggested using parameter expansion with patterns in http://lists.gnu.org/archive/html/bug-bash/2006-02/msg00020.html: $ foo=bar $ echo ${foo^} ## Convert first character Bar $ echo ${foo^^} ## Convert all characters BAR $ echo ${foo^[a-m]} ## Convert first character that matches pattern Bar $ echo ${foo^^[a-m]} ## Convert all characters that match pattern BAr -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: [bash4.2] ${v//[/} bug?
On Tue, 15 Feb 2011, Chet Ramey wrote: On 2/15/11 6:18 AM, Clark J. Wang wrote: For following script: var='[hello' echo ${var//[/} With bash 4.1 it outputs hello but with 4.2 it outputs [hello . And bash 4.2 with compat41 on still outputs [hello . Bug? Or Bug fixed? It's a bug, and I will release a patch. In the meantime, see if the attached patch does the right thing on your platform. On Mandriva, I get '[hello'; after applying the patch I get 'hello'. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: multi-line commands in the history get split when bash is quit
On Sat, 5 Feb 2011, Michael Witten wrote: On Sat, Feb 5, 2011 at 18:02, Jon Seymour jon.seym...@gmail.com wrote: The version I tried on Linux 3.2.25 does have a .bash_history format that could support it, but it still behaved the same way. How do you mean? I'm running bash version 4.1.9(2)-release on GNU/Linux, and the resulting history file doesn't seem like it's storing anything more than lines of text naively dumped from the multi-line example. According to the man page, HISTTIMEFORMAT ... If this variable is set, time stamps are written to the history file so they may be preserved across shell sessions. However this is not done in any version of bash that I can find. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Mapfile callback access to current line
On Mon, 17 May 2010, Chet Ramey wrote: On 4/15/10 11:56 PM, DennisW wrote: Mapfile would be that much more powerful if the callback function had access to the current line. Is there any chance this might be added in the future? Sure, there's a chance. What would be the most useful form? A shell variable that lives for the duration of the execution of the callback function? [A somewhat belated reply!] It appears that the assignment is made after the function is called rather than before. I would like the value passed to the callback function to be the index of the line just read (and already assigned to the array). IOW, this script would print the file: xx() { printf %3d %s\n $1 ${l[$1]} } mapfile -c1 -C xx -t l ~/.bashrc Now, ${l[$1]} is empty; it would be great if it contained the line just read. -- Chris F.A. Johnson, http://cfajohnson.com/ Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: 'help set' missing '--'
On Mon, 10 Jan 2011, Jan Schampera wrote: the help output for the set builtin command misses '--'. It's there: SYNOPSIS set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...] -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: 'help set' missing '--'
On Mon, 10 Jan 2011, Christopher Roy Bratusek wrote: On Monday 10 January 2011 09:06:42 Chris F.A. Johnson wrote: On Mon, 10 Jan 2011, Jan Schampera wrote: the help output for the set builtin command misses '--'. It's there: SYNOPSIS set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...] Hmm, one could read it as -- --a --b and so on, maybe it could be improved. Agreed. Perhaps: set [-[-abefhkmnptuvxBCHP]] [-o option-name] [arg ...] -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: cd with multiple arguments?
On Mon, 13 Dec 2010, Stephane CHAZELAS wrote: 2010-12-13, 12:04(+00), Marc Herbert: [...] True, bash does not come with a vast library of ready-to-use functions. Neither is there any such reference library available externally. Or is there? Yes, they're called commands or programs or software. People tend to forget that before all a shell is a command line interpreter. If you're finding yourself writing complex shell functions that don't make use of external commands, then you're heading the wrong direction with your shell, or you are heading in one direction with the wrong medium (i.e. you need a programming language, not a shell). I stongly disagree with that statement. The shell *is* a programming language, especially with the extensions in bash. In recent years I have stopped using any other language; the shell is more than adequate for all my programming needs. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Clear Screen
On Tue, 30 Nov 2010, Ajay Jain wrote: Hi, I use bash on Xterm. While working you press Ctrl-L, so that the screen gets cleared and you see the currently line only. But you may want to see the last outputs/prints. However, if you do a Ctrl-L/clear command, these prints go away. In that case, what can you use so that you clear the screen of the prints/outputs from last command. But in case you want to see the last output, you can just go scroll up/pageup. I looked the manpage but this info is not available. This would be a function of the terminal (xterm) not bash. Take a look at the options to xterm (man xterm). (There may not be an option that does what you want.) -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: IFS=':' set -- aa:bb:cc:dd # Fails to set $@
On Wed, 1 Dec 2010, ste...@syslang.net wrote: Configuration Information [Automatically generated, do not change]: Machine: i386 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i386' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i386-redhat-linux-gnu' -DCONF_VENDOR='redhat' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables uname output: Linux saturn.syslang.net 2.6.27.41-170.2.117.fc10.i686.PAE #1 SMP Thu Dec 10 10:48:30 EST 2009 i686 athlon i386 GNU/Linux Machine Type: i386-redhat-linux-gnu Bash Version: 3.2 Patch Level: 39 Release Status: release Description: It may be me, but I tried something that I thought should work, but it does not. I want to use the set command to parse data and I want the IFS variable to be in force during the set command. This does not work. So far, every other use of var=val cmd seems to work fine. Only this one plays funny. Repeat-By: IFS=':' set -- aa:bb:cc:dd echo $1 # After this runs, $1 is aa:bb:cc:dd instead of aa Instead, I have to say something like: oldIFS=$IFS IFS=':' set -- aa:bb:cc:dd IFS=$oldIFS BTW, the same behavior happens in bash4. Fix: Offered in the constructive spirit to see if this needs to be fixed or if this is a deliberate or known behavior. That is the way it should behave. The line is parsed before IFS is set. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: ionice bash pid in bash_profile Fails
On Mon, 22 Nov 2010, Roger wrote: On Mon, Nov 22, 2010 at 11:58:25AM -0500, Greg Wooledge wrote: On Mon, Nov 22, 2010 at 07:41:48AM -0900, Roger wrote: On Mon, Nov 22, 2010 at 08:39:49AM -0500, Greg Wooledge wrote: ionice -c 2 -n 0 -p `pidof bash` If you want the PID of the current shell process, use $$ instead. Here's the error I get when logging into a virtual terminal and $HOME/.bash_profile executes or is read in: ionice: ioprio_set failed: No such process Perhaps pidof fails to find the -bash process due to the leading dash? Who knows? Who cares? Use $$ to get the PID of the shell. The following works like a charm: # See ionice manfile - give high priority to Bash ionice -c 2 -n 0 -p `echo $$` Why are you using echo? ionice -c 2 -n 0 -p $$ -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: associative array assignment from the output of a function
On Fri, 22 Oct 2010, Andreas Schwab wrote: Axel axel.aze...@laposte.net writes: After your answer, I checked and I think the error message is not related to the variable name collision : [a...@axel-asus plugins]$ unset foo [a...@axel-asus plugins]$ func() { echo [a]=5 [b]=10 } [a...@axel-asus plugins]$ declare -A foo=( $(func) ) $ declare -A foo=('[a]=5') Drop the qotes: declare -A foo=( [a]=5 ) bash: foo: [a]=5: must use subscript when assigning associative array $ eval declare -A foo=($(echo '[a]=5')); echo ${foo[a]} 5 -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: bash auto complete malloc 'assertion botched' error
On Sat, 9 Oct 2010, Gerard Seibert wrote: On Fri, 8 Oct 2010 16:51:36 -0400 Fletcher Johnson flt.john...@gmail.com articulated: Configuration Information [Automatically generated, do not change]: Machine: i486 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i486-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall uname output: Linux kiwi 2.6.31-22-generic #65-Ubuntu SMP Thu Sep 16 15:48:58 UTC 2010 i686 GNU/Linux Machine Type: i486-pc-linux-gnu Bash Version: 4.0 Patch Level: 33 Release Status: release Description: Typing the following in the shell produces... fletc...@kiwi:~$ cd '\ malloc: unknown:0: assertion botched free: start and end chunk sizes differ Aborting... Repeat-By: typing cd '\ or ls \ will reproduce the above bug Using: GNU bash, version 4.1.7(2)-release (amd64-portbld-freebsd8.1) does not seem to produce that error. Nor does 4.0.28(2)-release on Mandriva 2009.1. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: asking for a better way to implement this
On Mon, 27 Sep 2010, Greg Wooledge wrote: On Mon, Sep 27, 2010 at 06:39:56PM +0200, Christopher Roy Bratusek wrote: It's a bad idea to alias rm. It would be better to use your xrm directly. If you alias rm and get in the habit of it protecting you, one of these days the alias won't be there and OOPS, gone! Well... I know what you mean, but I'm using GNU/Linux for seven years now, it's now almost impossible to learn to use `xrm' instead of `rm'. Besides, it won't disappear somewhen, it's hardcoded (and bound to other stuff, which I know whether it exists or not). You might reinstall your OS one day, either due to hardware failure or simply upgrading. Then you might forget to build the rm alias. Or you might get a job working on Unix systems. The systems at work will not have your rm alias. Or you might be on a friend's computer You get the idea, I hope. Or you might put it in a script, expecting to be prompted, and lose files you need. Aliases are not expanded in a script. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: asking for a better way to implement this
On Sun, 26 Sep 2010, Christopher Roy Bratusek wrote: btw. How can I remove the last arguement ${!#} ? I tried args=${@:-${!#}} but that won't work. args=( $@ ) unset args[$#-1] set -- ${ar...@]} -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: How to deal with space in command line?
On Sat, 18 Sep 2010, Peng Yu wrote: stat --printf %y %n\n `find . -type f -print` I could use the following trick to stat each file separately. But I prefer to stat all the files at once. I'm wondering if there is any easy way to converted the strings returned by find if there are special characters such as space by adding '\' in front them? This will supply as many files as possible as arguments to stat: find . -type f -exec stat --printf %y %n\n + -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Bash style of if-then-else?
On Mon, 23 Aug 2010, Dennis Williamson wrote: If you're writing a Bash-specific script then it's preferable to use double square brackets (see http://mywiki.wooledge.org/BashFAQ/031). if [[ -f $file ]] then do something fi I'd avoid non-portable syntax unless it offers a significant advantage over standard syntax. [[ ... ]] is not standard, and offers little over the standard syntax. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Issues when func name is the same with an alias
On Fri, 6 Aug 2010, Clark J. Wang wrote: On Thu, Aug 5, 2010 at 4:06 PM, Marc Herbert marc.herb...@gmail.com wrote: Le 04/08/2010 15:29, Clark J. Wang a écrit : I do not agree. Aliases are much simpler to use than functions. Please provide examples. The following is a part of my aliases. I'll have to write much more code if I define them all as functions. This is much more code: F(){ find $@; } than: alias F=find I don't think functions are better than aliases here. Any idea? Many reasons why functions are generally better have already been given. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: RFE -or- Howto?
On Mon, 2 Aug 2010, Linda Walsh wrote: But then we've devolved to really ugly. I like the look of (a b c) = (1 2 3). At least the allows it to be on one line though not so attractively, but using the multiline redirection just gets too unslightly for words. A minor loss of prettiness is negligible compared to portability. It makes it clear that you are no longer doing what I want, a multi-variable assignment. It *is* a multi-variable assignment. But that's my sense of what looks readable in codeYMMV. On 8/2/2010 3:51 PM, Chris F.A. Johnson wrote: On Mon, 2 Aug 2010, Dennis Williamson wrote: It's called a here string. And the same thing can also be accomplished with the more portable here document: read a b c d . 1 2 3 4 . -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: basic pattern match Question...newbie doesn't understand (!...@#$@$)
On Sun, 1 Aug 2010, Linda Walsh wrote: I have: w=/home/law/bin/package: line 5: type: xx: not found The =~ operator is suppose to use the RH Expr as a ext.-regex. So why doesn't this match and print not found? if [[ $w =~ .*not found.* ]]; then echo not found; fi It prints nothing. Seems like such a basic concept. Sorry, this newbie needs help on such trivial matters. :-( When quoted, the right-hand argument is matched as a string, not an expression. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Naming convention of bash script filenames
On Sun, 11 Jul 2010, Peng Yu wrote: Hi, I think that that may not be a unique naming convention for bash script filenames. But I use the following. For an executable bash script I use the suffix .sh. For a bash script that is only source-able but runnable, I use the suffix .bashrc. People may use different conventions. I just want to see what most people use and follow the common practice. Could anybody give me any suggestions? Like Bob, and for the same reasons, I do not use any suffix for a script once it is completed. I do, however, use a suffix when I'm working on a script: -sh I do my development on the -sh version, then copy that to the bin directory, without the suffix, when I've finished. That way, I can test the script with -sh, and continue working on it, without affecting the production copy. (The support scripts for this are in the last chapter of my first book, Shell Scripting Recipes.) -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Bash cannot kill itself?
On Wed, 30 Jun 2010, Clark J. Wang wrote: On Wed, Jun 30, 2010 at 1:40 PM, Jan Schampera jan.schamp...@web.de wrote: Clark J. Wang wrote: Running a cmd in background (by ) would not create subshell. Simple testing: #!/bin/bash function foo() { echo $$ } echo $$ foo ### END OF SCRIPT ### The 2 $$s output the same. This doesn't mean that it doesn't create a subshell. It creates one, since it can't replace your foreground process. This makes sense. It just shows that $$ does what it should do, it reports the relevant PID of the parent (main) shell you use. Then what's the problem with my script in my original mail? Seems like Bash does not handle the signal in a real-time way. The special variable $$ refers to the current process, even if it has the same numeric value as the parent script. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Bash cannot kill itself?
On Wed, 30 Jun 2010, Clark J. Wang wrote: On Wed, Jun 30, 2010 at 12:38 PM, Chris F.A. Johnson ch...@cfajohnson.comwrote: On Wed, 30 Jun 2010, Clark J. Wang wrote: I have a bash script like this: #!/bin/bash trap 'echo killed by SIGALRM; exit 1' ALRM function wait_kill() { sleep 5 kill -ALRM $$ } wait_kill sleep 3600 ### END OF THE SCRIPT ### It does not work as I expected. The running script was not terminated after 5 seconds. So what's wrong here? $$ refers to the subshell. There's no subshell here, I think. The background process invoked by . Try: trap 'echo killed by SIGALRM; exit 1' ALRM function wait_kill() { sleep 5 kill -ALRM $pid } pid=$$ wait_kill sleep 3600 -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: How to supply a string with space in it as parameter to a function?
On Wed, 23 Jun 2010, Peng Yu wrote: Hi, According to man bash, I thought that $@ instead of $* can help me pass a string with space as a parameter. But it is not. Would you please show me how to print 'b c' as a single argument in the following code? Always quote variable references unless you have a good reason not to. #!/usr/bin/env bash function f { #for i in $*; for i in $@; do echo $i done } for i in $@ ## note the quotes do echo $i ## better is: printf %s\n $i done Or, without a loop: printf %s\n $@ f a 'b c' d e f g $ ./main.sh a b c d e f g -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Question if bug: declaration of an associative array within a function
On Tue, 15 Jun 2010, Rainer Rehak wrote: Hey there, is it a bug, that the declaration of an associative array within a function does not survive till after the function, with primitive variables on the other hand that concept works well. It's not a bug. It's an unfortunate side effect from 'declare' being a duplicate of the (non-standard) typeset builtin. If would be much more useful (and semantically accurate), if it just did what its name implies, and left the 'local' builtin for declaring variable local to a function. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: How to autocomplete after 'which'?
On Fri, 21 May 2010, Peng Yu wrote: On Fri, May 21, 2010 at 11:19 AM, Marc Herbert marc.herb...@gmail.com wrote: Le 21/05/2010 16:25, Peng Yu a ?crit : When I type something after 'which', something means a command. However, bash doesn't do command completion for the argument after 'which'. Is there a way to configure bash behave depending on the context (in this case, do autocomplete after 'which')? By the way it is better to use type instead of which. which is often misleading, compare for instance: type pwd which pwd which is misleading in many other cases. Since pwd is a shell command, when /bin/pwd is actually used? In shells that don't have built-in pwd? And all POSIX shells have the $PWD variable. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: How to make a directory name with '/' in it?
On Sun, 16 May 2010, Peng Yu wrote: I tried the following command to create a dir with '/' in the name. But it only create a directory with name 'm'. Is there a way to make a directory with '/' in the name? mkdir m\/\/ There are two characters that cannot be in a file or directory name: / and NUL. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Help with sed
On Sat, 17 Apr 2010, William Park wrote: On Fri, Apr 16, 2010 at 01:22:24AM -0700, Radim wrote: Hello, I have such script: (ONLY THIS THREE LINES ARE THE COMMANDS ) content=$(cat $script | sed '/function codecs/,/fi;/d'); Which will fail if $script contains whitespace, and cat is unnecessary: content=$( sed '/function codecs/,/fi;/d' $script) content=$(echo $content | sed -n '/mandriva/,/fi;}/p'); content=$(echo $content | sed '/^\s*urpmi[:space:]--auto/p'); If you don't quote $content, echo will put it all on one line. content=$(echo $content | sed -n '/mandriva/,/fi;}/p'); content=$(echo $content | sed '/^\s*urpmi[:space:]--auto/p'); -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: How cd to a directory with special characters like environment\\-?
On Fri, 9 Apr 2010, Marc Herbert wrote: Le 08/04/2010 22:58, Peng Yu a ?crit : I make the following directory and try to cd to it. But I can't. Could you let me know what is the correct way of doing so? $ mkdir environment\\- $ cd environmen\\- -bash: cd: environmen-: No such file or directory In such situations I find completion (TAB) really great since it does the hard quoting work for you (and does no typo). That, or up-arrow (or Ctrl-P) to recall previous command. -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: declare -A a=b crashes bash
On Fri, 9 Apr 2010, Dennis van Dok wrote: 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-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall uname output: Linux camilla 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.0 Patch Level: 33 Release Status: release Description: Typing 'declare -A a=b' crashes bash with a segmentation fault. Repeat-By: Type 'declare -A a=b'. I can confirm that in 4.0, but it works in 4.1 Time to upgrade? -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: How cd to a directory with special characters like environment\\-?
On Fri, 9 Apr 2010, Greg Wooledge wrote: On Fri, Apr 09, 2010 at 11:59:20AM -0400, Chris F.A. Johnson wrote: On Fri, 9 Apr 2010, Marc Herbert wrote: Le 08/04/2010 22:58, Peng Yu a ?crit : $ mkdir environment\\- $ cd environmen\\- -bash: cd: environmen-: No such file or directory In such situations I find completion (TAB) really great since it does the hard quoting work for you (and does no typo). That, or up-arrow (or Ctrl-P) to recall previous command. As long as we're being exhaustively thorough... ... or cd $_ to reuse the last word of the previous command. ... or cd !$to reuse the last word in csh-style history expansion. Personally, I disable csh-style history expansion, though. Same here. I want printable characters to appear on my screen when I type them. Anything else is ^#...@-*! In my .bashrc: histchars= -- Chris F.A. Johnson, http://cfajohnson.com Author: Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress) Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Re: Return status of command substitution with $(...) gets lost
On Thu, 4 Mar 2010, Ettelbrueck, Heiko wrote: 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 wdfd00221495a 2.6.27.42-0.1-xen #1 SMP 2010-01-06 16:07:25 +0100 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.1 Patch Level: 0 Release Status: release Description: There is a function which runs some external tool. Both the tool's output and its exit status are relevant for further execution of the bash script. - The tool's is stored into a (new) local variable, which is then processed further. - The tool's exit status is retrieved from the $? variable. Important detail: The local variable is declared and defined in the same step with local VARNAME=$(do something). Problem: The $? variable is always 0 after that statement. The return status is that of the command, local. -- Chris F.A. Johnson http://cfajohnson.com === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Re: Namespace problem with pipe into a braced group
On Tue, 23 Feb 2010, t...@icada.com wrote: Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc -I/usr/src/packages/BUILD/bash-3.1 -L/usr/src/packages/BUILD/bash-3.1/../readline-5.1 Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-suse-linux-gnu' -DCONF_VENDOR='suse' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -O2 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -D_GNU_SOURCE -DRECYCLES_PIDS -Wall -pipe -g -fPIE -fbranch-probabilities uname output: Linux t60 2.6.18.8-0.13-default #1 SMP Thu Nov 6 13:35:13 UTC 2008 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-suse-linux-gnu Bash Version: 3.1 Patch Level: 17 Release Status: release Description: I would have expected the output to be 2 in both cases. My mistake or yours? :-) Repeat-By: a=1; echo foo;{ a=2; }; echo $a # output: 2 a=1; echo foo|{ a=2; }; echo $a # output: 1 Bug or feature? Standard behaviour; all components of a pipeline are executed in a subshell. -- Chris F.A. Johnson http://cfajohnson.com === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Re: Confused about how bash breaks input into words
On Tue, 23 Feb 2010, Eric Blake wrote: According to Allen Halsey on 2/23/2010 3:50 PM: Hi, I'm trying to understand bash's parsing model. I read in the manual that the shell breaks the input into words and operators, obeying the quoting rules described in Quoting. These tokens are separated by metacharacters. Another good reference is POSIX: http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 Taking this simple example: [...@host ~] $ echo The date is $(date +'%Y-%m-%d') 2010-02-23 Breaking this into words, using the above rule, results in: --- - echoword space metacharacter The word space metacharacter dateword space metacharacter is word space metacharacter So far, so good. But you missed that: $(date +'%Y-%m-%d') is an entire word (basically, an unquoted $ character consumes until the end of the shell substitution, command substitution, or arithmetic substitution, and that entire scan becomes part of the current word being parsed). This confuses me because, intuitively, I feel that the command substitution, $(date +'%Y-%m-%d'), should be treated as a single word. Yes, it is a single word. But it is subject to wordsplitting: $ print %s\n $(date +'%Y %m %d') 2010 02 23 -- Chris F.A. Johnson http://cfajohnson.com === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Re: Is there a special variable for the directory where the script is in?
On Fri, 12 Feb 2010, Peng Yu wrote: $0 gives the file name of the script. I could use several shell command to get the directory where the script is in. But I'm wondering if there is an easy-to-use variable that refers to the directory where the script is in? $0 normally gives the full path to the file, so: ${0%/*} -- Chris F.A. Johnson http://cfajohnson.com === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Re: Is there a special variable for the directory where the script is in?
On Thu, 11 Feb 2010, Eric Blake wrote: According to Chris F.A. Johnson on 2/11/2010 4:23 PM: On Fri, 12 Feb 2010, Peng Yu wrote: $0 gives the file name of the script. I could use several shell command to get the directory where the script is in. But I'm wondering if there is an easy-to-use variable that refers to the directory where the script is in? $0 normally gives the full path to the file, so: ${0%/*} No, $0 normally gives the argv[0], which matches how the file was invoked. Or, if it was found in $PATH, the full path to the file. That is how scripts are normally executed. If it was invoked by absolute path (or even an anchored invocation, such as ./script), then you can compute it yourself. Otherwise, you have to recreate the PATH walk in your script to determine where the script was eventually located, and hope that the script was not invoked in such a way that argv[0] does not match the name of the script being run. Look at any configure script generated by autoconf for a sample of how complex it can be to portably locate $myself. And, of course, there is rarely a good reason to need to know the location. -- Chris F.A. Johnson http://cfajohnson.com === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
Re: Passing variables to and from custom programs
On Sun, 7 Feb 2010, Mike Stroyan wrote: On Sat, Feb 06, 2010 at 05:35:21PM -0800, DennisW wrote: On Feb 6, 5:37 pm, djackn jack.nadel...@yahoo.com wrote: Result = myIpExec(${IPaddr1} ${IPaddr2} ${IPaddr3} ${IPaddr4}) myIpExec is a c program that normally uses scanf to prompt the user for the IP addresses and returns 0 or 1. I plan to use the script to test the program for various inputs. It is more likely that this would work: Result=$(echo {IPaddr1} ${IPaddr2} ${IPaddr3} ${IPaddr4} | myIpExec) Note that there are no spaces around the equal sign. If the result of 'myIpExec' is output to stdout then you could put that into a shell variable with the syntax that DennisW showed you. But you may have a problem with parsing it because any prompt for the IP addresses will be included at the front of that variable. If the result of 'myIpExec' is actually a return value from main() then you would access that as the shell variable $? just after the program is run. The bash 'here string' notation could be used as an alternative to the echo pipeline notation. It is not as portable. But I like the way it looks in shell script. It is used like this- myIpExec {IPaddr1} ${IPaddr2} ${IPaddr3} ${IPaddr4} Result=$? The portable equivalent is: myIpExec EOF {IPaddr1} ${IPaddr2} ${IPaddr3} ${IPaddr4} EOF -- Chris F.A. Johnson http://cfajohnson.com === Author: Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress) Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)