Re: q// / qq// syntax or built-ins please ?

2017-03-24 Thread Vladimir Marek
While quoting can be difficult at time, one can make his life simpler

DELIM=\'
CHAR="[^$DELIM]"
REGEX="$CHAR*$DELIM($CHAR+)$DELIM$CHAR*"

$ echo "

Error: Cannot find file '/missing/file_1'.

Error: Cannot find file '/missing/file_2'.

" | while read line; do
if [[ $line =~ $REGEX ]]; then
echo "${BASH_REMATCH[1]}"
fi
done
/missing/file_1
/missing/file_2


Care has to be taken though, CHAR can't be for example

CHAR=ab
WORD="$CHAR*"

as that becomes 'ab*' which is not '(ab)*'

Personally, I would probably use perl.

-- 
Vlad


On Thu, Mar 23, 2017 at 08:40:35PM +, Jason Vas Dias wrote:
> Please , in some future versions of bash, could it provide
> support / help for avoiding "quoting hell", in such situations
> as :
> 
> $ echo "
> 
> Error: Cannot find file '/missing/file_1'.
> 
> Error: Cannot find file '/missing/file_2'.
> 
> "  |  while read line; do
>cmd='if [[ '$'"'"$line"$'"'' =~
> ^[^'"\\'"']*['"\\'"']([^'"\\'"']+)['"\\'"'][^'"\\'"']*$ ]]; then echo
> ${BASH_REMATCH[1]}; fi;';
>   echo "$cmd" | bash -;
> done
> 
> See what I have to do to match lines containing a non-empty
> single-quoted string ?
> ie. I just want to cut-and-paste such lines from the output of some
> application, and
> weed out the empty lines and print the  single-quoted string in lines
> containing them (only!), with a simple bash command. If you replace
> "echo $cmd | bash -" with
> 'eval "$cmd"' , it does not work, because the double-quotes which I
> had painstakingly inserted with '$'"''  get removed somehow by eval -
> why is this?
> ie, only if "$line" is empty, does bash evaluate the text:
>'if [[ "" = ... ]]; then ...'
> else, for the lines I want to match, it would evaluate eg. :
> + eval 'if [[ Error: Cannot find file '\''/missing_file_1'\''.\" =~
> ^[^\\\'\'']*[\\\'\'']([\\\'\'']+)[\\\'\''][^\\\'\'']*$ ]]; then echo
> ${BASH_REMATCH[1]}; fi;'
> + set +x
> ( nothing printed - the single quotes are stripped)
> + eval 'if [[ \"\" =~
> ^[^\\\'\'']*[\\\'\'']([\\\'\'']+)[\\\'\''][^\\\'\'']*$ ]]; then echo
> ${BASH_REMATCH[1]}; fi;'
> ++ [[ "" =~ ^[^\']*[\']([\']+)[\'][^\']*$ ]]
> + set +x
> +
> 
> I think bash needs some kind of "q/.../'" and 'qq/../' syntax / built-ins, or
> whatever syntax its author likes,  like PERL has, whereby the  single quote
> ("'") or double quote ('"') respectively are totally ignored within
> '/.../'  parameter
> strings, which should use a different quoting character than '"' or
> "'" to delineate
> them.
> 
> If the author won't develop these, I will & will send a patch.
> 
> Regards,
> Jason
> 



Re: pipefail with SIGPIPE/EPIPE

2017-03-24 Thread Greg Wooledge
On Thu, Mar 23, 2017 at 10:14:01PM -0700, Pádraig Brady wrote:
> OK let's not derail this into a discussion specific to errexit.
> Can we please improve things?
> You say to not use errexit, and instead use `|| exit 1` where appropriate.
> In that case can we fix this case?
> 
>   set -o pipefail
>   yes | head -n1 || exit 1
>   echo this is skipped

What do you think is broken, here?

imadev:~$ yes | head -n1
y
imadev:~$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="141" [1]="0")

I don't see any problem in bash's behavior.  It's exiting because you
asked it to exit if the pipe failed, and the pipe failed.  The pipe
failed because yes(1) returned a nonzero exit code, and you turned on
the pipefail option.

What exactly are you asking to change?



Re: q// / qq// syntax or built-ins please ?

2017-03-24 Thread Eduardo Bustamante
Remember that bash's grammar is derived from the specification of the
POSIX shell 
(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html).
Also, any addition to the bash grammar should be backwards compatible
(or enabled with a shopt, disabled by default), to avoid breaking
already working scripts.

Due to the complexity of the above limitations, I'd just use perl or
another language. It's not worth the effort. So don't feel discouraged
if you send patches and these are rejected.



Re: [BUG] With null IFS, ${1+$*}, ${var-$*}, etc. don't generate fields

2017-03-24 Thread Martijn Dekker
Op 18-03-17 om 14:40 schreef Martijn Dekker:
> Op 27-02-17 om 21:03 schreef Chet Ramey:
>> If you think you have a winning argument, initiate a new discussion with
>> the Austin Group.  You might want to dig up the mail archives from
>> October, 2014 and look at the discussion that preceded interpretation 888.
> Thanks for the heads-up. I'm finding some time to do that now.

Bug confirmed by Geoff Clare.

http://www.austingroupbugs.net/view.php?id=1129#c3646

Thanks,

- M.




Re: pipefail with SIGPIPE/EPIPE

2017-03-24 Thread Pádraig Brady
On 24/03/17 04:57, Greg Wooledge wrote:
> On Thu, Mar 23, 2017 at 10:14:01PM -0700, Pádraig Brady wrote:
>> OK let's not derail this into a discussion specific to errexit.
>> Can we please improve things?
>> You say to not use errexit, and instead use `|| exit 1` where appropriate.
>> In that case can we fix this case?
>>
>>   set -o pipefail
>>   yes | head -n1 || exit 1
>>   echo this is skipped
> 
> What do you think is broken, here?
> 
> imadev:~$ yes | head -n1
> y
> imadev:~$ declare -p PIPESTATUS
> declare -a PIPESTATUS=([0]="141" [1]="0")
> 
> I don't see any problem in bash's behavior.  It's exiting because you
> asked it to exit if the pipe failed, and the pipe failed.  The pipe
> failed because yes(1) returned a nonzero exit code, and you turned on
> the pipefail option.
> 
> What exactly are you asking to change?

I would like bash to treat SIGPIPE specially in this case,
as it's not an error, rather the standard "back pressure"
mechanism used in pipes.  The fact that SIGPIPE kills
by default is only a shortcut mechanism allowing processes
to exit automatically without changing their code.
The shell should not treat this as a real error though.

I.E. so I can write code like:

  set -o pipefail
  vv=$(yes | head) || exit 1
  echo finished

which will exit if yes(1) or head(1) segfault
or otherwise exit(1) etc., but proceed normally.

thanks,
Pádraig



Parameter operator P should probably strip \[ and \] characters

2017-03-24 Thread Torka Noda
Hi,

(Currently using Bash-4.4_p12 on Gentoo GNU/Linux).

My PS1 contains colors, and thus \[ ... \] sequences around
colors, for proper line wrapping on the command-line.

I want to fake this prompt from my ~/.bashrc, because OCD,
before I execute some commands printing stuffs in the shell.

The problem is, using `echo -e "${PS1@P}ls"` will show
glyphs for the non-printing characters "\[" and "\]", instead
of stripping them.

From what I understand, \[ and \] characters are only useful for
the prompts, right?

If so, then the parameter operator P should probably strip them.

Workaround:

_PS1="$PS1"
_PS1="${_PS1//\\[}"
_PS1="${_PS1//\\]}"

echo -e "${_PS1@P}ls"
ls


Thanks.



Bash aliases erroneously expanded in 'case' patterns in some conditions

2017-03-24 Thread Torka Noda
Configuration Information [Automatically generated, do not
change]: Machine: x86_64
OS: linux-gnu
Compiler: x86_64-pc-linux-gnu-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./include -I.
-I./include -I./lib
-DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
-DSTANDARD_UTILS_PATH='/bin:/usr/bin:/sbin:/usr/sbin'
-DSYS_BASHRC='/etc/bash/bashrc'
-DSYS_BASH_LOGOUT='/etc/bash/bash_logout'
-DNON_INTERACTIVE_LOGIN_SHELLS -DSSH_SOURCE_BASHRC
-march=ivybridge -O2 -pipe -Wno-parentheses
-Wno-format-security uname output: Linux localhost 4.1.x-gentoo
#1 SMP PREEMPT Sun Mar 12 05:04:06 CET 2017 x86_64 Intel(R)
Core(TM) i7-3770 CPU @ 3.40GHz GenuineIntel GNU/Linux Machine
Type: x86_64-pc-linux-gnu

Bash Version: 4.4
Patch Level: 12
Release Status: release

Description:
When sourcing a script (rather than executing it), if
the "in" keyword of a case construct is on its own line
(rather than on the first line of the construct with
"case", or on the same line as the first pattern), then
the pattern is expanded as an alias, if it exists.

Thus the word will be checked silently against the
expanded alias, and likely fail, which is unexpected.

If the alias contains a space (command argument), then
Bash will fail with the following error message:

bash: foo2.sh: line 9: syntax error near unexpected
token `words'
bash: foo2.sh: line 9: `two words '

Repeat-By:

# 

#!/bin/bash
alias foo='oneword'
foo_word='foo'
#
# Fails silently to match 'foo':
#
case "$foo_word"
in
foo) echo 'Test 1!';;
esac

# 

#!/bin/bash
alias foo='two words'
foo_word='foo'
#
# Errors out:
#
case "$foo_word"
in
foo) echo 'Test 2!';;
esac

# 

Source these scripts with `source` (it happens in my
~/.bashrc too).

If you comment the alias line (and run `unalias foo`
from your shell, to clear the alias), then both scripts
will work without issue.


Thanks.