Re: The "-e" test ingores broken links
2016-10-14 07:08:22 +0700, Peter & Kelly Passchier: > WHich docs? > If I do "help test" it states: "All file operators except -h and -L are > acting on the target of a symbolic link, not on the symlink itself, if > FILE is a symbolic link." [...] Yes, to test for file existence, the syntax is [ -e "$file" ] || [ -L "$file" ] Or: ls -d -- "$file" > /dev/null 2>&1 But even then, if it returns false, that doesn't necessarily mean the file doesn't exist. It could also be that it's impossible to tell. If you remove the 2>&1 above, the error message would help you differentiate between the cases. If using zsh instead of bash, you can also check the $ERRNO variable to see if [ -e ] failed because of ENOENT or something else. See also https://stackoverflow.com/questions/638975/how-do-i-tell-if-a-regular-file-does-not-exist-in-bash/40046642#40046642 -- Stephane
Add support for array .pop()
Bash has elegant and powerful constructs like `mapfile', yet it is missing something as easy as an array "pop". Extract the last value of an array at the same time as removing it from the array. Is this the best one can do? $ a=(1 2 3); v=${a[-1]}; unset 'a[-1]'; printf '%s\n' "$v" "${a[@]}" The 2-step approach gets tiresome after a while. For positional parameters, it _does_ have `shift'... ... maybe it could add a `pop`, somehow?
Re: forked before bash subshell
Daniel Colascione wrote: One such case is Cygwin --- I'm not sure how "contrived" it is. Cygwin has an old-fashioned non-COW fork, and to add insult to injury, process creation generally is very slow (~100ms). It pays to eliminate subshells in that environment. Given what Cygwin has to work around in Windows -- it is very contrived. MS has copy-on-write available to MS processes, that it's not usable in Cygwin isn't surprising given that most of Windows is closed-source. But if you really want bash on your windows, use a native copy. It's not as likely to have the same problems (https://techcrunch.com/2016/03/30/be-very-afraid-hell-has-frozen-over-bash-is-coming-to-windows-10/) Apparently there is a Windows Subsystem for Linux that is currently in Beta for Win10: http://www.howtogeek.com/265900/everything-you-can-do-with-windows-10s-new-bash-shell/
Re: Add support for array .pop()
On Sat, Oct 15, 2016 at 11:12 AM, Marco Ippolito wrote: > Bash has elegant and powerful constructs like `mapfile', > yet it is missing something as easy as an array "pop". > > Extract the last value of an array at the same time as > removing it from the array. > > Is this the best one can do? > > $ a=(1 2 3); v=${a[-1]}; unset 'a[-1]'; printf '%s\n' "$v" "${a[@]}" > > The 2-step approach gets tiresome after a while. > > For positional parameters, it _does_ have `shift'... > ... maybe it could add a `pop`, somehow? > Since you're using Bash-4.3 (or 4.4), you can create a function that uses declare -n: $ function array_pop { declare -n __a=$1; __=${__a[-1]}; unset '__a[-1]'; } $ a=(1 2 3); array_pop a; printf '%s\n' "$__" "${a[@]}" 3 1 2 And my simple rule to using functions that process variables with -n: don't pass variables that begin with two underscores. There's another way to avoid variable name conflicts, and that is to prefix the reference variables with the name of the function itself, but I find that already an overkill. You can also improve the function by adding sanity checks, but that's the basic concept of it. -- konsolebox
Re: Add support for array .pop()
On Sat, Oct 15, 2016 at 5:41 PM, lolilolicon wrote: > > pop() { > local -n _a=$1 > printf -v "$2" "${_a[-1]}" and of course I meant printf -v "$2" '%s' "${_a[-1]}" The keyword is nameref if you haven't heard of it, so you can look it up in the man page :)
Re: Add support for array .pop()
On Sat, Oct 15, 2016 at 11:12 AM, Marco Ippolito wrote: > Bash has elegant and powerful constructs like `mapfile', > yet it is missing something as easy as an array "pop". > > Extract the last value of an array at the same time as > removing it from the array. > > Is this the best one can do? > > $ a=(1 2 3); v=${a[-1]}; unset 'a[-1]'; printf '%s\n' "$v" "${a[@]}" > > The 2-step approach gets tiresome after a while. Does this help? pop() { local -n _a=$1 printf -v "$2" "${_a[-1]}" unset _a[-1] } declare -a a=(a b c) while ((${#a[@]})); do pop a v declare -p a v done
Re: Add support for array .pop()
On Sat, Oct 15, 2016 at 7:45 PM, Marco Ippolito wrote: > On Sat, Oct 15, 2016 at 05:41:32PM +0800, lolilolicon wrote: >> pop() { >> local -n _a=$1 >> printf -v "$2" "${_a[-1]}" >> unset _a[-1] >> } >> >> declare -a a=(a b c) >> while ((${#a[@]})); do >> pop a v >> declare -p a v >> done > > > What I particularly like about your `pop()' function is that it works even > when called from within a function, rather than from the global scope, as you > do in your snippet. > > Specifically, if we assume that: > > - a is a global array > - a is also a local array inside function1 > - pop is called from function1 > > it still "does the right thing (TM)", when called before and after the local > declaration. I think it's because bash uses dynamic scoping. > > Feels like the nameref acts as if it referenced `scope.identifier'. > > I would still like to see similar functionality included in Bash, though. > > Why do you prefer: > > declare -a a=(a b c) > > to: > > a=(a b c) > > Guess: "Explicit is better than implicit"? (Zen of Python) I don't want to think too much about any possible side effects... so I just write what I mean. > > I see it more as: "Redundant code is... redundant". > > Why the underscore in: > > local -n _a=$1 > > Guess: to visually signal it's a nameref? To avoid name conflicts. If you use say, a instead of _a, you will get cyclic reference. That's a big pitfall with nameref (combined with dynamic scoping), if you're not careful with your variable naming conventions. > > Not sure about identifier naming conventions in Bash but that, subjectively, > seems to allude to something else, like "unused", or "local", etc. > > I am generally not particularly in favour of "Hungarian notation" but, > perhaps, `a_ref' or `a_nameref' rather than `_a' in your case? I don't think bash has a universal style standard like Python...
Re: Add support for array .pop()
On Sat, Oct 15, 2016 at 7:58 PM, Marco Ippolito wrote: > On Sat, Oct 15, 2016 at 07:32:23PM +0800, konsolebox wrote: >> On Sat, Oct 15, 2016 at 11:12 AM, Marco Ippolito >> wrote: >> > Bash has elegant and powerful constructs like `mapfile', >> > yet it is missing something as easy as an array "pop". >> > >> > Extract the last value of an array at the same time as >> > removing it from the array. >> > >> > Is this the best one can do? >> > >> > $ a=(1 2 3); v=${a[-1]}; unset 'a[-1]'; printf '%s\n' "$v" "${a[@]}" >> > >> > The 2-step approach gets tiresome after a while. >> > >> > For positional parameters, it _does_ have `shift'... >> > ... maybe it could add a `pop`, somehow? >> > >> >> Since you're using Bash-4.3 (or 4.4), you can create a function that >> uses declare -n: >> >> $ function array_pop { declare -n __a=$1; __=${__a[-1]}; unset '__a[-1]'; } >> $ a=(1 2 3); array_pop a; printf '%s\n' "$__" "${a[@]}" >> 3 >> 1 >> 2 >> >> And my simple rule to using functions that process variables with -n: >> don't pass variables that begin with two underscores. There's another >> way to avoid variable name conflicts, and that is to prefix the >> reference variables with the name of the function itself, but I find >> that already an overkill. >> >> You can also improve the function by adding sanity checks, but that's >> the basic concept of it. >> >> -- >> konsolebox > > Nice function but there is something I dislike about it. > > I find the alteration of global state as a side-effect in contradiction with > the notion of self-containment of functions, e.g.: > > $ unset x; printf '|%s|\n' "$x"; f() { x=y; }; f; printf '|%s|\n' "$x" > || > |y| > > > The potential overwriting of a pre-existing identifier `__' is, in my eyes, > undesirable. > > Shouldn't I be able to call a function without worrying about what it could do > to my current scope? (This may be a debatable point for some). Oh so you actually meant my use of __. Sorry I just got used to that practice. I treat __ as a "volatile global variable" i.e., one should expect that it can change on every call to another function. I prefer things done that way since it's more efficient, and/or is more doable in older versions of bash. This time I use it as a result variable, but sometimes I use it as a common "iterator", or just a temporary variable. You can follow lolilolicon's suggestion if you want to pass another variable that would store the value instead. My version would be this: function array_pop { declare -n __a=$1 __v=$2; __v=${__a[-1]}; unset '__a[-1]'; } By the way, please use "Reply to all" so your message would also be sent to bug-bash. You can also have that configured in Gmail so that it would be the default behavior. -- konsolebox
Re: Add support for array .pop()
On Sat, Oct 15, 2016 at 10:50 PM, konsolebox wrote: > > My version would be this: > > function array_pop { declare -n __a=$1 __v=$2; __v=${__a[-1]}; unset > '__a[-1]'; } > Here's another version which avoids local or nameref variables, pop() { [[ -v $1 ]] || return set -- "$1[-1]" "$2" eval set -- \"\$@\" \"\$\{"$1"\}\" printf -v "$2" '%s' "$3" unset "$1" }
Re: Add support for array .pop()
On 10/14/16 11:12 PM, Marco Ippolito wrote: > Bash has elegant and powerful constructs like `mapfile', > yet it is missing something as easy as an array "pop". There is source code support for operations like pop and similar. If you think it's worthwhile, you might look at writing a loadable builtin to implement the operations you'd like to see. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: forked before bash subshell
On 10/15/2016 12:23 AM, L. A. Walsh wrote: Daniel Colascione wrote: One such case is Cygwin --- I'm not sure how "contrived" it is. Cygwin has an old-fashioned non-COW fork, and to add insult to injury, process creation generally is very slow (~100ms). It pays to eliminate subshells in that environment. Given what Cygwin has to work around in Windows -- it is very contrived. Maybe the internals. From the perspective of programs like bash, Cygwin is a mostly ordinary POSIX environment, one with lots of users and that deserves full support. MS has copy-on-write available to MS processes, that it's not usable in Cygwin isn't surprising given that most of Windows is closed-source. It has nothing to do with being closed source and everything to do with the win32 subsystem (under which Cygwin runs) not being designed to cope with process duplication. But if you really want bash on your windows, use a native copy. It's not as likely to have the same problems (https://techcrunch.com/2016/03/30/be-very-afraid-hell-has-frozen-over-bash-is-coming-to-windows-10/) It doesn't do the same thing. Cygwin is an integrated POSIXish environment. Apparently there is a Windows Subsystem for Linux that is currently in Beta for Win10: http://www.howtogeek.com/265900/everything-you-can-do-with-windows-10s-new-bash-shell/ SFU and similar do not interact with the win32 subsystem as closely as Cygwin and so can't provide the same experience. IMHO, you might as well run a VM.
Re: Broken PIPESTATUS with --disable-job-control
Chet Ramey wrote: > On 9/18/16 11:20 PM, Felix Janda wrote: > > >>> Notice that the configure script disables job-control when a run-time > >>> test (which could easily be a built-time test) fails. So by default, > >>> a cross-compiled bash will have this bug. > >> > >> Which test? > > > > I am referring to BASH_SYS_JOB_CONTROL_MISSING. > > Sure. I'm asking which part of that run-time test can easily be converted > to a build-time test that handles conditional compilation and definitions. below a patch to make things more concrete: --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1357,7 +1357,7 @@ [AC_REQUIRE([BASH_SYS_SIGNAL_VINTAGE]) AC_MSG_CHECKING(for presence of necessary job control definitions) AC_CACHE_VAL(bash_cv_job_control_missing, -[AC_TRY_RUN([ +[AC_TRY_COMPILE([ #include #ifdef HAVE_SYS_WAIT_H #include @@ -1367,42 +1367,35 @@ #endif #include -/* Add more tests in here as appropriate. */ -main() -{ /* signal type */ #if !defined (HAVE_POSIX_SIGNALS) && !defined (HAVE_BSD_SIGNALS) -exit(1); +#error #endif /* signals and tty control. */ #if !defined (SIGTSTP) || !defined (SIGSTOP) || !defined (SIGCONT) -exit (1); +#error #endif /* process control */ #if !defined (WNOHANG) || !defined (WUNTRACED) -exit(1); +#error #endif /* Posix systems have tcgetpgrp and waitpid. */ #if defined (_POSIX_VERSION) && !defined (HAVE_TCGETPGRP) -exit(1); +#error #endif #if defined (_POSIX_VERSION) && !defined (HAVE_WAITPID) -exit(1); +#error #endif /* Other systems have TIOCSPGRP/TIOCGPRGP and wait3. */ #if !defined (_POSIX_VERSION) && !defined (HAVE_WAIT3) -exit(1); +#error #endif - -exit(0); -}], bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing, -[AC_MSG_WARN(cannot check job control if cross-compiling -- defaulting to missing) - bash_cv_job_control_missing=missing] +], bash_cv_job_control_missing=present, bash_cv_job_control_missing=missing )]) AC_MSG_RESULT($bash_cv_job_control_missing) if test $bash_cv_job_control_missing = missing; then
Re: forked before bash subshell
XiaoBing Jiang wrote: Thank you for your explain! #!/bin/bash (cd /tmp && exec sleep 20) & echo "end" Then, instead of having: $ ./foo end $ ps f -t pts/5 PID TTY STAT TIME COMMAND 7287 pts/5Ss 0:00 bash 20165 pts/5R+ 0:00 \_ ps f -t pts/5 20160 pts/5S 0:00 /bin/bash ./foo 20161 pts/5S 0:00 \_ sleep 20 When I run your program, I get: ./foo; ps f -t pts/3 end PID TTY STAT TIME COMMAND 91677 pts/3Ss 0:00 -bash 96604 pts/3R+ 0:00 \_ ps f -t pts/3 96603 pts/3S 0:00 sleep 20 I don't see a line corresponding to your '/bin/bash ./foo' line. Isn't my output what you show in the next example? Is it what was wanted? You will have: $ ./foo end $ ps f -t pts/5 PID TTY STAT TIME COMMAND 7287 pts/5Ss 0:00 bash 20173 pts/5R+ 0:00 \_ ps f -t pts/5 20172 pts/5S 0:00 sleep 20 This is what you wanted, right?
Re: forked before bash subshell
Daniel Colascione wrote: On 10/15/2016 12:23 AM, L. A. Walsh wrote: Daniel Colascione wrote: One such case is Cygwin --- I'm not sure how "contrived" it is. Cygwin has an old-fashioned non-COW fork, and to add insult to injury, process creation generally is very slow (~100ms). It pays to eliminate subshells in that environment. Given what Cygwin has to work around in Windows -- it is very contrived. Maybe the internals. From the perspective of programs like bash, Cygwin is a mostly ordinary POSIX environment, one with lots of users and that deserves full support. --- Oh? It's a hack to bring POSIX-like functionality to allow for programs and scripts to be run on a Windows machine. FWIW, I've used it for about 15+ years. I use almost identical bash-login+startup scripts on my windows box as I do on my Linux box. The scripts do check if they are running on cygwin and define a function for later ease-of-use: if ! type -f cygwin 2>/dev/null ; then read SYSTEM_KERNEL HOSTNAME OSTYPE <<<"$($_prg_uname -sno)" if [[ $OSTYPE =~ Cygwin ]]; then cygwin () { return 0; } else cygwin () { return 1; } fi export -f cygwin fi Later I use 'cygwin' to setup a proxy for my winhost and read a few win/cygwin specific aliases in (like mklink): if cygwin ; then source /etc/local/cygwin/aliases.sh fi MS has copy-on-write available to MS processes, that it's not usable in Cygwin isn't surprising given that most of Windows is closed-source. It has nothing to do with being closed source and everything to do with the win32 subsystem (under which Cygwin runs) not being designed to cope with process duplication. --- I'm fairly sure that the win32 API is insufficient for emulating the POSIX environment and that cygwin uses other Windows NT calls to get its job done. CoW is available in the NT-kernel, but since windows processes don't "fork" (they issues a request to a process-spawner to create a new process -- an expensive and clumsy task (windows has a high overhead for creating new processes, but last I saw any statistics (some time ago), it was faster in creating new threads compared to linux. That's partly due to linux not having threads as a separate kernel object, but emulating them via processes. I.e. - a linux thread is, _basically_, another process (though, *very* slightly lighter weight) with more common areas shared with the parent processes than a normal fork call would share. The fact that cygwin has done so much is a testament to the teams hard work at looking under the covers of the closed-source OS, since much of what they need to do, not only isn't part of the Win32 API, but isn't officially published by MS anywhere. But if you really want bash on your windows, use a native copy. It's not as likely to have the same problems (https://techcrunch.com/2016/03/30/be-very-afraid-hell-has-frozen-over-bash-is-coming-to-windows-10/) It doesn't do the same thing. Cygwin is an integrated POSIXish environment. Nothing ever does the exact same thing as anything else -- even itself. However, if you look at the pics it shows the drives mounted under a directory (they used /mnt) just like in cygwin (which uses /cygwin by default), but I find better integration twixt cygwin & windows by using '/' as my prefix-dir, putting my drives at /c, /d, /s ... and my bin+lib dirs @ /bin and /lib on C. Also the MS-bash instance is running in the same file-system namespace as Windows. A directory listing of /mnt/c shows a permission denied error for a few Admin-only files, and then shows the normal C:-drive root contents. And just like in cygwin, they use '/' as the file-separator (since NT can use either). Note, the article says this: While Microsoft pitches this feature as “Bash shell” environment, it’s actually an underlying compatibility layer that allows you to run Linux software on Windows. That means you can run other shells instead of Bash, if you prefer them. --- I.e. MS's bash will run on a compatibility layer -- just like bash running under cygwin. Apparently there is a Windows Subsystem for Linux that is currently in Beta for Win10: http://www.howtogeek.com/265900/everything-you-can-do-with-windows-10s-new-bash-shell/ SFU and similar do not interact with the win32 subsystem as closely as Cygwin and so can't provide the same experience. IMHO, you might as well run a VM. SFU is no longer available -- and this is not using that subsystem. BTW -- to respond to this statement: Daniel Colascione wrote: It pays to eliminate subshells in that environment. --- You really want bash to function differently on cygwin than it does on any other platform? Or, you would really suggest that bash re-architect itself on all platforms to support it running on cygwin, when, at the same time, MS is bringing their own version of bash to windows? That seems like a very risky proposition with little to no payout. There's no guara
Re: BASH_SUBSHELL reset to 0 on EXIT trap in aubshell
On 10/13/16 4:00 AM, Martijn Dekker wrote: > bash resets BASH_SUBSHELL to 0 when executing an EXIT trap, even if the > EXIT trap is executed in a subshell. > > echo $(trap 'echo $BASH_SUBSHELL' EXIT; echo $BASH_SUBSHELL) > Actual output: 1 0 > Expected output: 1 1 This is a reasonable suggestion for both command and process substitution. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: forked before bash subshell
On 10/11/16 10:14 PM, s7v7nisla...@gmail.com wrote: > 1. the script to reproduce > bash-4.4$ cat t.sh > (cd /tmp && sleep 20) & > > echo "end" > > > 2. run it > bash-4.4$ bash t.sh > end > > 3. script end, but there is a new forked script. > bash-4.4$ ps -ef | grep t.sh > 501 50268 1 0 10:09AM ttys0150:00.00 bash t.sh > 501 50275 50181 0 10:10AM ttys0150:00.00 grep t.sh > > > > question: > when using sh -> dash, It will not fork before subshell, what's the different? > > why bash bahavior like this? is that a bug? It's not a bug; it's an opportunity for optimization. It's like this because it hasn't come up as a performance problem. I'll take a look at it. There are probably several opportunities like this. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/
Re: Question about arithmetic expression grammar
On 10/10/16 9:57 AM, Stephane Chazelas wrote: > Now, if we look at the C spec, the way +++ is parsed is down to > tokenisation that will also go for the longest operator first. > > There --test+++3 would be tokenised as -- test ++ + 3 which > would lead to a syntax error as test++ isn't an lvalue. > > bash works differently. > > From what I understand from past discussions on the subject here > bash doesn't treat it as a syntax error and tries instead to tokenise > those incorrect ++/-- into multiple + or - operators if possible. This is more or less correct. Bash doesn't treat a token as a post- increment or post-decrement unless the previous token is a string. Since the previous token is a number (based on the evaluation of the pre- increment), these are treated as a sequence of unary pluses. In this case, we can add some additional error checking. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/