Re: 'cd' if HOME is unset

2023-01-02 Thread Christian Kujau
On Sun, 25 Dec 2022, Michael Cheponis wrote:
> Maybe it should print "$HOME is not set" in that case?

Some shells do just that, some fail silently, and some figure it out w/o 
$HOME set:

$ for s in /bin/{sh,csh,ksh} /usr/pkg/bin/{bash,zsh}; do \
   echo "### ${s}"; ${s} -c "cd /tmp; unset HOME; cd; pwd"; echo; done

### /bin/sh
cd: HOME not set
/tmp

### /bin/csh
/home/dummy

### /bin/ksh
/bin/ksh: cd: no home directory (HOME not set)
/tmp

### /usr/pkg/bin/bash
/usr/pkg/bin/bash: line 1: cd: HOME not set
/tmp

### /usr/pkg/bin/zsh
/tmp



Oh, csh is special and it uses "home" instead of "HOME", and fails hard 
when it's unset:


$ /bin/csh -c "cd /tmp; unset HOME home; cd; pwd"
cd: No home directory.


(NB: there's nothing NetBSD specific here, the same happens on other platforms 
too)

C.
-- 
BOFH excuse #240:

Too many little pins on CPU confusing it, bend back and forth until 10-20% are 
neatly removed. Do _not_ leave metal bits visible!


Re: 'cd' if HOME is unset

2022-12-26 Thread Robert Elz
Date:Mon, 26 Dec 2022 10:41:25 -0800
From:Michael Cheponis 
Message-ID:  


  | Well, as a zsh user:

What zsh does you'd need to take up with zsh developers.   But it is
one of 2 shells I tested which don't require HOME to be set for "cd".
zsh I am not all that surprised about.  It tends not to concentrate
a lot on conformance with other shells, but rather on what its designers
believe is better for its users.(The other that does not error is dash).

  | $ echo $HOME
  | /usr/mac
  | $ unset HOME
  | $ echo $HOME
  |
  | $ zsh -c cd
  | $(no change in directory, no error msg)

No error message, yes, but are you sure there was no change in
directory?   (Even if that change was into the directory it started from).

jacaranda$ (cd /; unset HOME; zsh -c 'cd; pwd')
/home/kre

Looks like it changed directory to me (from / to /home/kre - my normal home).

  | in all cases, directory does not change when HOME is not defined.

Note that in the test cases (like "(unset HOME; zsh -c cd)") the subshell
(parentheses) are so the "unset HOME" doesn't affect the shell from which
the command is run (you won't need to set HOME again after the test), and
the cd is run only in the context of the shell that runs it, so only that
process has its directory changed - in this test, that shell exits
immediately after, so doing the change this way is normally pointless,
here, it was done solely for the purpose of viewing the error message
(if any).

In the form I use above, rather than simply exit, the shell that ran
the "cd" then ran "pwd" after, to reveal what its directory was now.
You could change the command string to "pwd; cd; pwd" to see before
and after directories.

kre



Re: 'cd' if HOME is unset

2022-12-26 Thread Michael Cheponis
Well, as a zsh user:

$ echo $HOME
/usr/mac
$ unset HOME
$ echo $HOME

$ zsh -c cd
$(no change in directory, no error msg)

also:

$ HOME=/usr/mac
$ echo $HOME
/usr/mac

$ (unset HOME; zsh -c cd)
$ (no error msg)


in all cases, directory does not change when HOME is not defined.


On Mon, Dec 26, 2022 at 9:47 AM Robert Elz  wrote:

> Date:Sun, 25 Dec 2022 15:33:57 -0800
> From:Michael Cheponis 
> Message-ID:   5rw...@mail.gmail.com>
>
>   | Maybe it should print "$HOME is not set" in that case?
>
> Did you try it?
>
> It is easy...
>
> (unset HOME; sh -c cd)
>
> or use ksh (or some other shell) instead of sh to test it.
>
> Script started on Tue Dec 27 00:01:34 2022
> jacaranda$ (unset HOME; sh -c cd)
> cd: HOME not set
> jacaranda$ (unset HOME; ksh -c cd)
> ksh: cd: no home directory (HOME not set)
> jacaranda$ exit
>
> Script done on Tue Dec 27 00:03:06 2022
>
>
> Note HOME  not $HOME  is not set, $HOME is, if
> HOME is set, a pathname, or if HOME is not set, "",
> neither of which makes any sense to describe as 'not set'.
>
> kre
>


Re: 'cd' if HOME is unset

2022-12-26 Thread Robert Elz
Date:Sun, 25 Dec 2022 15:33:57 -0800
From:Michael Cheponis 
Message-ID:  


  | Maybe it should print "$HOME is not set" in that case?

Did you try it?

It is easy...

    (unset HOME; sh -c cd)

or use ksh (or some other shell) instead of sh to test it.

Script started on Tue Dec 27 00:01:34 2022
jacaranda$ (unset HOME; sh -c cd)
cd: HOME not set
jacaranda$ (unset HOME; ksh -c cd)
ksh: cd: no home directory (HOME not set)
jacaranda$ exit

Script done on Tue Dec 27 00:03:06 2022


Note HOME  not $HOME  is not set, $HOME is, if
HOME is set, a pathname, or if HOME is not set, "",
neither of which makes any sense to describe as 'not set'.

kre


Re: 'cd' if HOME is unset

2022-12-26 Thread Michael Cheponis
Maybe it should print "$HOME is not set" in that case?


On Sun, Dec 25, 2022 at 2:52 PM Valery Ushakov  wrote:

> On Sat, Dec 24, 2022 at 22:32:22 -0500, Jan Schaumann wrote:
>
> > Robert Elz  wrote:
> > > Why bother?
> >
> > I happily admit that it's a rare edge case. I simply
> > find it surprising that 'cd' gives up if HOME is
> > unset.  Seems unintuitive to me.
>
> Some would say, "gives up", some would say it makes you aware you have
> a problem. :)
>
> DWIM is enticing, sure, but at some point it trasmutes into that
> JavaScript "WAT" talk moment.
>
> -uwe
>


Re: 'cd' if HOME is unset

2022-12-25 Thread Valery Ushakov
On Sat, Dec 24, 2022 at 22:32:22 -0500, Jan Schaumann wrote:

> Robert Elz  wrote:
> > Why bother?
> 
> I happily admit that it's a rare edge case. I simply
> find it surprising that 'cd' gives up if HOME is
> unset.  Seems unintuitive to me.

Some would say, "gives up", some would say it makes you aware you have
a problem. :)

DWIM is enticing, sure, but at some point it trasmutes into that
JavaScript "WAT" talk moment.

-uwe


Re: 'cd' if HOME is unset

2022-12-24 Thread Robert Elz
Date:Sat, 24 Dec 2022 22:32:22 -0500
From:Jan Schaumann 
Message-ID:  

  | I happily admit that it's a rare edge case. I simply
  | find it surprising that 'cd' gives up if HOME is
  | unset.  Seems unintuitive to me.

It is how it is defined to work, and always has been.
Only dash and zsh seem to handle that case, no other
shells bother.   (I am a little surprised that dash does,
their general philosophy tends towards minimalist implementation,
with almost nothing that isn't required).

Better is just to always have HOME set.

For /bin/sh ~ works without HOME, so you could define

cd() {
case "$#" in
0)  set -- ~ ;;
esac
command cd "$@"
}

if you wanted to.   But that's not required to work either (I'm
not surprised that dash doesn't expand ~ when HOME is not set,
that's more in line with what I'd expect ... though tilde expansion
working is, in general, more useful, than cd with no args when
HOME is unset, so if a shell was to do just one, I'd generally do
it the way we do (as does bash)).

kre

ps: I am a little surprised that csh acts this way though, it
started from the Thompson sh (ie: pre 7th edition) and back then
there was no environment, and while csh had vars (incl home)
it couldn't have cd depend upon what was in the environment, and
had to either use the passwd db, either for "cd" or to init "home"
or both.   I guess that has been changed since.




Re: 'cd' if HOME is unset

2022-12-24 Thread Jan Schaumann
Robert Elz  wrote:
> Why bother?

I happily admit that it's a rare edge case. I simply
find it surprising that 'cd' gives up if HOME is
unset.  Seems unintuitive to me.

-Jan


Re: 'cd' if HOME is unset

2022-12-24 Thread Robert Elz
Why bother?It is already clear that one cannot depend upon this
working, and nothing normally should ever have HOME unset, unless that
is done deliberately (perhaps even to prevent a simple "cd" from
going there).

kre



Re: 'cd' if HOME is unset

2022-12-24 Thread Jan Schaumann
Jan Schaumann  wrote:

> "A common extension when HOME is undefined is to get
> the login directory from the user database for the
> invoking user. This does not occur on System V
> implementations."
> 
> I'm surprised that /bin/sh does not use the user's
> home directory from getpwuid() in that case

Attached is a proposed patch to change this such that
/bin/sh and /bin/ksh would fall back to
getpwuid()->pw_dir if HOME is unset as suggested by
POSIX as a "common extension".

What do you think?

-Jan
Index: ksh/c_ksh.c
===
RCS file: /cvsroot/src/bin/ksh/c_ksh.c,v
retrieving revision 1.29
diff -u -p -r1.29 c_ksh.c
--- ksh/c_ksh.c 3 Jun 2018 12:18:29 -   1.29
+++ ksh/c_ksh.c 24 Dec 2022 23:01:47 -
@@ -10,6 +10,7 @@ __RCSID("$NetBSD: c_ksh.c,v 1.29 2018/06
 #endif
 
 #include 
+#include 
 #include 
 
 #include "sh.h"
@@ -30,6 +31,7 @@ c_cd(wp)
int phys_path;
char *cdpath;
char *fdir = NULL;
+   struct passwd *p;
 
while ((optc = ksh_getopt(wp, _opt, "LP")) != EOF)
switch (optc) {
@@ -55,8 +57,12 @@ c_cd(wp)
if (!wp[0]) {
/* No arguments - go home */
if ((dir = str_val(global("HOME"))) == null) {
-   bi_errorf("no home directory (HOME not set)");
-   return 1;
+   if ((p = getpwuid(getuid())) == NULL) {
+   bi_errorf("getpwuid() failed: %s", 
strerror(errno));
+   return 1;
+   } else {
+   dir = p->pw_dir;
+   }
}
} else if (!wp[1]) {
/* One argument: - or dir */
Index: ksh/ksh.Man
===
RCS file: /cvsroot/src/bin/ksh/ksh.Man,v
retrieving revision 1.26
diff -u -p -r1.26 ksh.Man
--- ksh/ksh.Man 26 Aug 2018 22:52:34 -  1.26
+++ ksh/ksh.Man 24 Dec 2022 23:01:48 -
@@ -1739,7 +1739,9 @@ An empty entry in the \fBCDPATH\fP entry
 If a non-empty directory from \fBCDPATH\fP is used, the resulting full
 path is printed to standard output.
 If \fIdir\fP is
-missing, the home directory \fB$HOME\fP is used.
+missing, the home directory \fB$HOME\fP is used;
+if \fB$HOME\fP is unset, the user's home directory is
+determined from the password database.
 If \fIdir\fP is
 \fB\-\fP, the previous working directory is used (see OLDPWD parameter).
 If \fB\-L\fP option (logical path) is used or if the \fBphysical\fP option
Index: sh/cd.c
===
RCS file: /cvsroot/src/bin/sh/cd.c,v
retrieving revision 1.50
diff -u -p -r1.50 cd.c
--- sh/cd.c 5 Jul 2017 20:00:27 -   1.50
+++ sh/cd.c 24 Dec 2022 23:01:48 -
@@ -43,6 +43,7 @@ __RCSID("$NetBSD: cd.c,v 1.50 2017/07/05
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -83,6 +84,7 @@ cdcmd(int argc, char **argv)
const char *path, *cp;
char *p;
char *d;
+   struct passwd *pwd;
struct stat statb;
int print = cdprint;/* set -o cdprint to enable */
 
@@ -97,8 +99,13 @@ cdcmd(int argc, char **argv)
dest = *argptr;
if (dest == NULL) {
dest = bltinlookup("HOME", 1);
-   if (dest == NULL)
-   error("HOME not set");
+   if (dest == NULL) {
+   if ((pwd = getpwuid(getuid())) == NULL) {
+   error("getpwuid() failed: %s", strerror(errno));
+   } else {
+   dest = pwd->pw_dir;
+   }
+   }
} else if (argptr[1]) {
/* Do 'ksh' style substitution */
if (!curdir)
Index: sh/sh.1
===
RCS file: /cvsroot/src/bin/sh/sh.1,v
retrieving revision 1.229
diff -u -p -r1.229 sh.1
--- sh/sh.1 18 Sep 2020 07:21:26 -  1.229
+++ sh/sh.1 24 Dec 2022 23:01:50 -
@@ -31,7 +31,7 @@
 .\"
 .\"@(#)sh.18.6 (Berkeley) 5/4/95
 .\"
-.Dd September 18, 2020
+.Dd December 24, 2022
 .Dt SH 1
 .\" everything except c o and s (keep them ordered)
 .ds flags abCEeFfhIiLmnpquVvXx
@@ -2431,7 +2431,9 @@ of utilities, the name for built-ins or 
 .\"
 .It Ic cd Oo Fl P Oc Op Ar directory Op Ar replace
 Switch to the specified directory (default
-.Ev $HOME ) .
+.Ev $HOME ,
+or, if unset, the home directory of the current user
+as specified in the password database).
 If
 .Ar replace
 is specified, then the new directory name is generated by replacing


'cd' if HOME is unset

2022-12-19 Thread Jan Schaumann
Hello,

POSIX requires that the 'cd' command use the $HOME
environment variable (if that is set) when no operand
is given.

It explicitly notes that behavior of 'cd' with no
operand when $HOME is unset is implementation defined.
It then notes:

"A common extension when HOME is undefined is to get
the login directory from the user database for the
invoking user. This does not occur on System V
implementations."

I'm surprised that /bin/sh does not use the user's
home directory from getpwuid() in that case:

$ pwd
/tmp
$ unset HOME
$ cd
cd: HOME not set
$ pwd
/tmp
$

This is the same for /bin/ksh and /bin/csh as well.

Did all these somehow inherit this from System V or
was there a reason why this wasn't implemented?

-Jan