coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: New utility suggestion: chdir(1)


From: Bernhard Voelker
Subject: Re: New utility suggestion: chdir(1)
Date: Tue, 29 Aug 2017 01:08:28 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0

On 08/27/2017 09:23 AM, Colin Watson wrote:
> From 0a74257b9fb7e02587b6c5553d8bc1b536249a7e Mon Sep 17 00:00:00 2001
> From: Colin Watson <address@hidden>
> Date: Sun, 27 Aug 2017 08:16:21 +0100
> Subject: [PATCH] env: add --chdir option
> 
> This is useful when chaining with other commands that run commands in a
> different context.
> 
> * NEWS (New features): Document the new option.
> * doc/coreutils.texi (env invocation): Likewise.
> * src/env.c (usage): Likewise.
> (main): Implement the new option.
> * tests/misc/env.sh: Test the new option.
> ---
>  NEWS               |  3 +++
>  doc/coreutils.texi | 17 +++++++++++++++++
>  src/env.c          | 20 ++++++++++++++++++++
>  tests/misc/env.sh  | 10 +++++++++-
>  4 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/NEWS b/NEWS
> index d37195e..60d5ca5 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -86,6 +86,9 @@ GNU coreutils NEWS                                    -*- 
> outline -*-
>  
>    expr supports multibyte strings for all string operations.
>  
> +  env now has a --chdir option to change to a new working directory before
> +  executing the subsidiary program.
> +

To me (as non-native), "new working directory" might sound like the
directory may be created at the same time, doesn't it?
Maybe
  s/to change to a new working directory/to change the working directory/
?

>  ** Improvements
>  
>    mv --verbose now distinguishes rename and copy operations.
> diff --git a/doc/coreutils.texi b/doc/coreutils.texi
> index 8f1cb4c..f127517 100644
> --- a/doc/coreutils.texi
> +++ b/doc/coreutils.texi
> @@ -16909,6 +16909,23 @@ environment.
>  @opindex --ignore-environment
>  Start with an empty environment, ignoring the inherited environment.
>  
> +@item --chdir=@var{dir}
> +@opindex --chdir
> +Change the working directory to @var{dir} before invoking @var{command}.
> +This differs from the shell built-in @command{cd} in that it starts
> +@var{command} as a subprocess rather than altering the shell's own working
> +directory; this allows it to be chained with other commands that run commands
> +in a different context.  For example:
> +
> +@example
> +# Run 'true' with /chroot as its root directory and /srv as its working
> +# directory.
> +chroot /chroot env --chdir=/srv true
> +# Run 'true' with /build as its working directory, FOO=bar in its
> +# environment, and a time limit of five seconds.
> +env --chdir=/build FOO=bar timeout 5 true
> +@end example
> +
>  @end table
>  
>  @cindex exit status of @command{env}
> diff --git a/src/env.c b/src/env.c
> index 63d5c2c..291fbb4 100644
> --- a/src/env.c
> +++ b/src/env.c
> @@ -33,11 +33,19 @@
>    proper_name ("Richard Mlynarik"), \
>    proper_name ("David MacKenzie")
>  
> +/* For long options that have no equivalent short option, use a
> +   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
> +enum
> +{
> +  CHDIR = CHAR_MAX + 1
> +};
> +
>  static struct option const longopts[] =
>  {
>    {"ignore-environment", no_argument, NULL, 'i'},
>    {"null", no_argument, NULL, '0'},
>    {"unset", required_argument, NULL, 'u'},
> +  {"chdir", required_argument, NULL, CHDIR},
>    {GETOPT_HELP_OPTION_DECL},
>    {GETOPT_VERSION_OPTION_DECL},
>    {NULL, 0, NULL, 0}
> @@ -63,6 +71,7 @@ Set each NAME to VALUE in the environment and run 
> COMMAND.\n\
>    -i, --ignore-environment  start with an empty environment\n\
>    -0, --null           end each output line with NUL, not newline\n\
>    -u, --unset=NAME     remove variable from the environment\n\
> +      --chdir=DIR      change working directory to DIR\n\
>  "), stdout);
>        fputs (HELP_OPTION_DESCRIPTION, stdout);
>        fputs (VERSION_OPTION_DESCRIPTION, stdout);
> @@ -81,6 +90,7 @@ main (int argc, char **argv)
>    int optc;
>    bool ignore_environment = false;
>    bool opt_nul_terminate_output = false;
> +  char const *newdir = NULL;
>  
>    initialize_main (&argc, &argv);
>    set_program_name (argv[0]);
> @@ -103,6 +113,9 @@ main (int argc, char **argv)
>          case '0':
>            opt_nul_terminate_output = true;
>            break;
> +     case CHDIR:
> +       newdir = optarg;
> +       break;

Please use tab-free indentation as throughout the whole coreutils
sources.

>          case_GETOPT_HELP_CHAR;
>          case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
>          default:
> @@ -154,6 +167,13 @@ main (int argc, char **argv)
>        usage (EXIT_CANCELED);
>      }
>  
> +  if (newdir)
> +    {
> +      if (chdir (newdir) != 0)
> +     die (EXIT_CANCELED, errno, _("cannot change directory to %s"),
> +          quoteaf (newdir));
> +    }
> +

Likewise.

>    execvp (argv[optind], &argv[optind]);
>  
>    int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
> diff --git a/tests/misc/env.sh b/tests/misc/env.sh
> index f2f6ba8..c409630 100755
> --- a/tests/misc/env.sh
> +++ b/tests/misc/env.sh
> @@ -18,7 +18,7 @@
>  
>  
>  . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
> -print_ver_ env
> +print_ver_ env pwd
>  
>  # A simple shebang program to call "echo" from symlinks like "./-u" or 
> "./--".
>  echo "#!$abs_top_builddir/src/echo simple_echo" > simple_echo \
> @@ -150,4 +150,12 @@ test "x$(sh -c '\c=d echo fail')" = xpass && #dash 0.5.4 
> fails so check first
>  returns_ 125 env -u a=b true || fail=1
>  returns_ 125 env -u '' true || fail=1
>  
> +# Verify changing directory.
> +mkdir empty || framework_failure_
> +returns_ 125 env --chdir=empty/nonexistent true || fail=1
> +curdir=$(env pwd) || fail=1
> +test "$curdir" = "$(pwd)" || fail=1

The above does not run CU's version of pwd, but instead
that of the shell.  The test therefore fails when "pwd -L"
!= "pwd -P" (and the implementation of coreutils and that
of the shell differs).

> +curdir=$(env --chdir=empty pwd) || fail=1
> +test "$curdir" = "$(cd empty && pwd)" || fail=1
> +
>  Exit $fail
> -- 

I therefore propose to squash in the following change:

diff --git a/tests/misc/env.sh b/tests/misc/env.sh
index c409630..7c864cd 100755
--- a/tests/misc/env.sh
+++ b/tests/misc/env.sh
@@ -153,9 +153,8 @@ returns_ 125 env -u '' true || fail=1
 # Verify changing directory.
 mkdir empty || framework_failure_
 returns_ 125 env --chdir=empty/nonexistent true || fail=1
-curdir=$(env pwd) || fail=1
-test "$curdir" = "$(pwd)" || fail=1
-curdir=$(env --chdir=empty pwd) || fail=1
-test "$curdir" = "$(cd empty && pwd)" || fail=1
+exp=$(cd empty && env pwd) || framework_failure_
+got=$(env --chdir=empty pwd) || fail=1

Thanks & have a nice day,
Berny



reply via email to

[Prev in Thread] Current Thread [Next in Thread]