Re: backtick to NOT set variable

2016-06-18 Thread Laurent Bercot


 Sorry it took so long. Please try the -I option to backtick and withstdinas
in the latest execline git and tell me if it works for you.

--
 Laurent


Re: backtick to NOT set variable

2016-05-20 Thread Laurent Bercot

On 18/05/2016 13:42, Max Ivanov wrote:

can backtick (or combination of other scripts commands) can be  to NOT
set env var on error?


 I'm pretty sure that any case can be achieved with the current behaviour,
but I agree that ugly contorsions are necessary for more than one case,
so I'm ok to add an option switch - but the semantics need to be right
(and it won't be -z, which I prefer to only use for something related to
reaping z-ombies)

 What exactly is the behaviour you want:

 - don't exit on error, just keep exec'ing
   + do you just define "error" as the subprocess exiting anything else
than 0 ?
 - but completely undefine the variable, in order for later tests such
as importas to pick that up?

 Is that right, or have I missed something?

--
 Laurent


Re: backtick to NOT set variable

2016-05-18 Thread Max Ivanov
>
>  Not if it succeeds.
>  However, backtick -i will exit on error: you can use that difference in
> program flow to create the sequence you need.

I didn't find a construct where rest of the program can be executed in
same process as `backtick`, or at least forked after `backtick`.
Closest I could find is `ifte` with `backtick` as as `progif` and 2
copies of the remaining part of the program in `progif` and `progthen`
which is obviously ugly beyond any limits


>> backtick -n MAYBE_ARG { /bin/false }
>> import -u MAYBE_ARG
>> s6-echo ${MAYBE_ARG} $@
>
>
>  Note that it's intentional that you always get an argument when
> expanding ${MAYBE_ARG}. That's a feature of execline.

Doesn't seem to be true, at least
```
import NOSUCHVAR
s6-echo ${NOSUCHVAR} $@
```
is equal to `s6-echo $@` if `NOSUCHVAR` is not an environment
variable. As you can see there is no explicit spitting, yet
`${NOSUCHVAR}` is substituted with no argument (not an empty
argument!)


>
>> I could add `-s` flag, to `import` and it solves problem for an empty
>> value,
>> but it also splits non empty value which is not desirable.
>
>
>  Use a splitting delimiter that cannot appear in your value.

```
import -d "\0" -s
```

gives me a syntax error,  anything else is just a magical value and I
am uncomfortable using it.


I can see that problem can be solved neatly with either:

1) introducing alternative to "cmd || :" shell construct, lets call it
`ignoreme` then it would be:
```
ignoreme backtick -i MAYBEARG { ... }
import -u MAYBEARG
...
```
but I can't see how it can be done in a model which execline follows.
It have to be like "foreground" but without a fork which seems not
doable.

2) introduce switch to a `backtick`  which doesn't set variable on
subprocess error. Here is the patch I just prepared, it is completely
untested, didn't even try to compile yet, but would be happy to hear
feedback on approach
diff --git a/src/execline/backtick.c b/src/execline/backtick.c
index 2deb9f3..ae952c8 100644
--- a/src/execline/backtick.c
+++ b/src/execline/backtick.c
@@ -9,13 +9,13 @@
 #include 
 #include 
 
-#define USAGE "backtick [ -i | -D default ] [ -n ] var { prog... } command..."
+#define USAGE "backtick [ -i | -D default ] [ -z ] [ -n ] var { prog... } command..."
 #define dieusage() strerr_dieusage(100, USAGE)
 
 int main (int argc, char const *const *argv, char const *const *envp)
 {
   char const *def = 0 ;
-  int insist = 0, chomp = 0 ;
+  int insist = 0, chomp = 0, skip_on_err = 0 ;
   PROG = "backtick" ;
   {
 subgetopt_t l = SUBGETOPT_ZERO ;
@@ -29,6 +29,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
 case 'n' : chomp = 1 ; break ;
 case 'i' : insist = 1 ; break ;
 case 'D' : def = l.arg ; break ;
+case 'z' : zkip_on_err = 1; break ;
 default : dieusage() ;
   }
 }
@@ -57,6 +58,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
 newargv[m++] = EXECLINE_BINPREFIX "withstdinas" ;
 if (insist) newargv[m++] = "-i" ;
 if (chomp) newargv[m++] = "-n" ;
+if (skip_on_err) newargv[m++] = "-z" ;
 if (def)
 {
   newargv[m++] = "-D" ;
diff --git a/src/execline/withstdinas.c b/src/execline/withstdinas.c
index c1e3c36..29a876c 100644
--- a/src/execline/withstdinas.c
+++ b/src/execline/withstdinas.c
@@ -17,8 +17,8 @@ int main (int argc, char const **argv, char const *const *envp)
 {
   subgetopt_t localopt = SUBGETOPT_ZERO ;
   stralloc modif = STRALLOC_ZERO ;
-  unsigned int modifstart ;
-  int insist = 0, chomp = 0, reapit = 0 ;
+  unsigned int modifstart = 0 ;
+  int insist = 0, chomp = 0, reapit = 0 , skip_on_err = 0 ;
   char const *def = 0 ;
   PROG = "withstdinas" ;
   for (;;)
@@ -31,6 +31,7 @@ int main (int argc, char const **argv, char const *const *envp)
   case 'n' : chomp = 1 ; break ;
   case 'D' : def = localopt.arg ; break ;
   case '!' : reapit = 1 ; break ;
+  case 'z' : skip_on_err = 1 ; break ;
   default : dieusage() ;
 }
   }
@@ -56,7 +57,9 @@ int main (int argc, char const **argv, char const *const *envp)
 strerr_diefu1sys(111, "waitpid") ;
   if (wait_estatus(wstat))
   {
-if (insist)
+if (skip_on_err)
+  modif.len = 2
+else if (insist)
   if (WIFSIGNALED(wstat)) strerr_dief1x(wait_estatus(wstat), "child process crashed") ;
   else strerr_dief1x(wait_estatus(wstat), "child process exited non-zero") ;
 else if (def)


Re: backtick to NOT set variable

2016-05-18 Thread Laurent Bercot

On 18/05/2016 13:42, Max Ivanov wrote:

can backtick (or combination of other scripts commands) can be  to NOT
set env var on error?


 Not if it succeeds.
 However, backtick -i will exit on error: you can use that difference in
program flow to create the sequence you need.



backtick -n MAYBE_ARG { /bin/false }
import -u MAYBE_ARG
s6-echo ${MAYBE_ARG} $@


 Note that it's intentional that you always get an argument when
expanding ${MAYBE_ARG}. That's a feature of execline. If you want an
empty ${MAYBE_ARG} to expand to zero word, you need to split the
substitution.



I could add `-s` flag, to `import` and it solves problem for an empty value,
but it also splits non empty value which is not desirable.


 Use a splitting delimiter that cannot appear in your value.

--
 Laurent