What shell do you guys use? - BSD

Users browsing this thread:
pkal
Long time nixers
On the topic of shells, does anyone know how to get ksh's "horizontal line scrolling" feature in bash? That's really the only thing (except maybe for the cleanness of ksh) that I notice and prefer over bash. I keep on using bash because of it's superior auto-completion, though.
wolf
Members
(18-06-2020, 03:13 PM)jkl Wrote: I admit that I hadn’t tested it on a real Solaris yet, but wouldn’t pkgsrc work?

Probably would work. But I can't due to some company rules. But I'll try it on OpenIndiana.
seninha
Long time nixers
(18-06-2020, 04:15 PM)zge Wrote: On the topic of shells, does anyone know how to get ksh's "horizontal line scrolling" feature in bash? That's really the only thing (except maybe for the cleanness of ksh) that I notice and prefer over bash. I keep on using bash because of it's superior auto-completion, though.

Put the following in your ~/.inputrc
Code:
set horizontal-scroll-mode on
eadwardus
Members
I use mksh as interactive shell, and rc/posix shell to write scripts. But for me, any shell with auto-completion serves its purpose as interactive shell, as i usually use it only to run commands.
pkal
Long time nixers
(21-06-2020, 12:21 PM)phillbush Wrote:
(18-06-2020, 04:15 PM)zge Wrote: On the topic of shells, does anyone know how to get ksh's "horizontal line scrolling" feature in bash? That's really the only thing (except maybe for the cleanness of ksh) that I notice and prefer over bash. I keep on using bash because of it's superior auto-completion, though.

Put the following in your ~/.inputrc
Code:
set horizontal-scroll-mode on

For some reason that didn't work on my system, but

Code:
set horizontal-scroll-mode On

did. Not as nice as ksh, but it works well.
seninha
Long time nixers
(08-07-2020, 08:16 AM)zge Wrote: For some reason that didn't work on my system, but

set horizontal-scroll-mode On

did. Not as nice as ksh, but it works well.

That's strange, the manual says:

Quote:Unrecognized variable names are ignored. When a variable value is read, empty or null values, "on" (case-insensitive), and "1" are equivalent to On. All other values are equivalent to Off.

Anyways...
One thing (other than <(command)) that makes me like bash more than ksh is that in ksh you can only rebind the keys in the emacs mode, you cannot rebind keys in the vi mode, while in bash you can rebind in both modes. Line editing in bash is much more involved.

That makes me think that shells should not be interactive, instead we should use a wrapper like rlwrap that does the interactive job of line editing and completion, leaving the command parsing and execution job for the shell itself. Thus, you could reuse the shell wrapper in other shells/prompts like debuggers and interpreters, and have a uniform interface for every shell. You could for example, use sh, plan9's rc and a lisp interpreter all with the same line editing keybindings.
jkl
Long time nixers
Don’t they all use readline anyway?

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
jkl
Long time nixers
Currently testing: The rather usable ion shell from Redox OS (seems to be rather resource-hungry in its default configuration though) and the desh which is a fork of the es shell with some additional interactivity, namely: a NIH alternative to libreadline.

Both are mostly undocumented. That’s fun.

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
injinj
Members
(01-10-2020, 05:52 AM)jkl Wrote: Currently testing: The rather usable ion shell from Redox OS (seems to be rather resource-hungry in its default configuration though) and the desh which is a fork of the es shell with some additional interactivity, namely: a NIH alternative to libreadline.

Both are mostly undocumented. That’s fun.

I ran the loop test:

Code:
; cat > loop2.es <<XX
> echo 'echo -n x' > test.sh
> let (i = 1) {
>   while {$$i :le 100} {
>     desh test.sh
>     i = <={%sum $$i 1}
>   }
> }
> echo x
> exit 0
> XX
; time desh loop2.es                                                    
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
0.08user 0.05system 0:00.14elapsed 100%CPU (0avgtext+0avgdata 4052maxresident)k
0inputs+8outputs (0major+24063minor)pagefaults 0swaps
; bash
$ time (for i in $(seq 1 1 100); do bash test.sh ; done)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
real    0m0.080s
user    0m0.038s
sys     0m0.045s

Bash almost twice as fast.
jkl
Long time nixers
Ah, the dev. Welcome to nixers and thank you for contributing this!

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
injinj
Members
I think that the missing shell in this discussion is Powershell. Powershell is like the SystemD for Windows, except with command line capabilities.
pyratebeard
Long time nixers
(01-10-2020, 05:48 PM)injinj Wrote: I think that the missing shell in this discussion is Powershell. Powershell is like the SystemD for Windows, except with command line capabilities.

"Aww, look at Windows trying to be a real operating system." - quote from an ex-colleague on Powershell

I could do with a shot of rum right now.
jkl
Long time nixers
The Powershell has an awful command line syntax, sadly.

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
injinj
Members
I tried posh on Linux for a couple of days, but none of the plugins worked, they all required Windows. The problem with higher level languages on the command line is that a shell's main duty is to fork processes. Once the shell is forked, the only communication available are inter process through a pipe. All of the environment is no longer shared.

I was thinking about storing the environment in a sqlite db and sharing it across shell forks.

In es:

Code:
; let (i = 0) { fn hello {echo $i; i = <={%sum $i 1}}}
; hello ; hello ; hello
0 1 2

The closure variable i is incremented after every invocation of hello, but if hello in a subprocess, then i doesn't change:

Code:
; echo `{hello ; hello ; hello}                                        
3 4 5
; echo `{hello ; hello ; hello}                                        
3 4 5

The subshell fork of the backquote operator causes the variable i to be copied and manipulated in the subshell. The same happens with the env in bash when a subshell is spawned.

If the environment were persistent, that might allow for fancier command line multi processing. Maybe a new subshell operator, for example:

Code:
# normal subshell fork copy env
$ echo $(i=hello ; echo $i)
hello
# shared subshell fork share env
$ echo %(i=hello ; echo $i) ; echo $i
hello
hello
venam
Administrators
(02-10-2020, 06:54 AM)injinj Wrote: The closure variable i is incremented after every invocation of hello, but if hello in a subprocess, then i doesn't change:
Code:
; echo `{hello ; hello ; hello}                                        
3 4 5
; echo `{hello ; hello ; hello}                                        
3 4 5

I think the second example of subprocess is missing.
injinj
Members
(02-10-2020, 06:56 AM)venam Wrote:
(02-10-2020, 06:54 AM)injinj Wrote: The closure variable i is incremented after every invocation of hello, but if hello in a subprocess, then i doesn't change:
Code:
; echo `{hello ; hello ; hello}                                        
3 4 5
; echo `{hello ; hello ; hello}                                        
3 4 5

I think the second example of subprocess is missing.

I could run the same echo command 100 times and it will still print 3 4 5. The reason is that the shell environment is forked, and then hello is run 3 times. I can capture this with ps like this:

Code:
; echo `{ps ax | grep desh > ps.out; hello ; hello ; hello} ; cat ps.out
3 4 5
5205 pts/0    Ss     0:00 -desh
17160 pts/0    S      0:00 -desh
17162 pts/0    S+     0:00 grep desh

; echo `{ps ax | grep desh > ps.out; hello ; hello ; hello} ; cat ps.out
3 4 5
5205 pts/0    Ss     0:00 -desh
17187 pts/0    S      0:00 -desh
17189 pts/0    S+     0:00 grep desh

The 5205 process is the desh running in the terminal connected to pts/0, the 17xxx process are subshells spawned using the backquote operator, these are running the hello functions.
ols
Members
I’m using ksh and bash depending on the machine for interactive shells. Thinking of moving to zsh

All scripts are written in sh wherever possible
jkl
Long time nixers
(15-11-2020, 04:30 PM)ols Wrote: Thinking of moving to zsh

Why?

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
ols
Members
(15-11-2020, 05:47 PM)jkl Wrote: Why?

I always thought it was a meme shell but I learned it’s 30 years old. Fancy a change an I know people rage about it a lot
mattrose
Members
I am desparately trying to get used to zsh after macos stopped shipping recent versions of bash.
yakumo.izuru
Members
for me it's either sh(1) (if FreeBSD), ash(1) (if Linux, usually busybox(1) provides it), ksh(1) (if OpenBSD), I don't know which shell uses NetBSD as I haven't looked much into it
Shrek
Members
I really like mksh. I'm not a very demanding shell user so I value simplicity and speed over features. I usually write scripts to automate a lot of commands or make a wrapper around existing programs that manipulates their text output.

(15-11-2020, 09:40 PM)mattrose Wrote: I am desparately trying to get used to zsh after macos stopped shipping recent versions of bash.

Check out Homebrew. They have lots of open source packages compiled for MacOS (including bash 5.1.16).

https://formulae.brew.sh/formula/bash
ckester
Nixers
ksh93, nowadays for no other reason than familiarity after many years of use.
jkl
Long time nixers
(15-11-2020, 09:40 PM)mattrose Wrote: I am desparately trying to get used to zsh after macos stopped shipping recent versions of bash.

macOS also has the tcsh. :)

--
<mort> choosing a terrible license just to be spiteful towards others is possibly the most tux0r thing I've ever seen
jkl
Long time nixers
(03-06-2020, 01:44 AM)jkl Wrote: rc is quite awesome on Plan 9 because all of its history commands are meant to be used with mouse chords. But I couldn’t even modify its prompt easily.

FWIW, I found out how to modify the prompt...:

1. Performance and resource usage

Code:
time (for i in $(seq 1 1 100); do rc test.sh; done)

Code:
real    0m0.093s
user    0m0.087s
sys     0m0.019s

vsz: 6504. Not bad.

2. Real-life test

Configuration ($HOME/.rcrc):

Code:
LANG=(de_DE.UTF-8)
TERM=(xterm-256color)
path=(/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /opt/local/bin $home/bin)

## Define the $prompt
prompt=('
'$USER'@'`hostname':'`pwd'
; ' '')

## Function definitions
## Reload the config file:
fn reload {
    . $home/.rcrc
}

## Update the prompt while cd:
fn cd {
    builtin cd $*
    && reload
}

Globbing: cd */*oo* moves into "shelltest/Foo".
Tab-completion: cd sh<tab>f<tab> does not work. I wonder if I could write a function to fix that.
History:
- Ctrl+R sh<Enter> performs cd shelltest/Foo.
- !! seems to not do anything (but I haven't even used that in the past few months).
- !-3 does neither (but I haven't even used that in the past few months).
Dependencies (on Debian Linux): libc, libreadline.

I like how rc does not misbehave just by feeding it an exclamation mark - the one thing that annoys me with the tcsh. I might keep it, I'll play with it for a while.
josuah
Long time nixers
(12-09-2022, 12:34 PM)jkl Wrote: cd sh<tab>f<tab> does not work. I wonder if I could write a function to fix that.
On plan 9, iirc, it is Ctrl + F, which sends a signal to RC, which shows completion. So it is something dependent on the rio integration. Maybe forks like https://github.com/benavento/rc would work better.

(12-09-2022, 12:34 PM)jkl Wrote: !! seems to not do anything (but I haven't even used that in the past few months).
On plan9port I think the " command does repeat the last non-" command, or eventually one matching the argument to ".
It will use /dev/text, but p9p emulates that (iirc unsharp() plan9port-specific command).

As a funny reminder: plan9port is the starting point for the Go language. Look at early Go version in C and you will recognise plan9 set of compilers, as packaged by plan9port.

There are a bunch of commits to remove plan9port specifics out of Go. : )
josuah
Long time nixers
Small tip: the most critical information that is missing from any default shell, in a portable way: the last command error code.

I do it this way:
Code:
% PS1='%${?#0} '
% true
% false
%1 true
% ^C
%130 true
%

The magic: $? contains the last error code, but having a "0" displayed all of the time is not nice, so to strip it, the parameter expansion ${var#glob} [1] strips the leading "0", which only appears for one value: 0: it remove the code when it is 0.

This is a bit tweaked and not very flexible, but very portable (for sh, no immediate equivalent for rc), and helps with catching "ok, there are error messages, but did 'make' return 1 or 0? Ah shit I did an 'ls', this long compilation exit code is lost forever!".

Another extremely useful (at times) feature is showing the date in the prompt: reason: it permits to measure time of execution of commands even when you forgot to run "date" before and after or run the command with a leading "time": "I let the command run the whole night and it worked! but... did it take 5 minutes or 5 hours? No can tell!"

Another extremely feature of the terminal st(1) (a bit off-topic, sorry), is the "-o iofile" flag that logs every I/O to a file.
Life-saver! I had 5GB of shell logs, but I have 100GB of free disk space, so why bother... On the other hand: "ok, I'm pushing the configuration to the router over ssh, let's review it once *issue a dump conf command on the router* all good, apply, still works... disconnect from router and call it a day! *client calls angry telling the network is dead* what? wait a minute... uh oh, no more ssh access, and I closed the terminal with the backlog, I do not know what went wrong, time to drive for 2h to the client's place with a new router at hand! Ah, no I do have the terminal I/O recording the conf dump command I did, and the exact sequence of commands I entered, including those of 5 days ago for fixing the same problem."

[1]: https://pubs.opengroup.org/onlinepubs/96...g_18_06_02
jkl
Long time nixers
I use the rc with readline port, not the p9p version. Maybe it works differently. (I sometimes use p9p because it has Sam and Acme, but most of the systems on which I want to use rc don’t even have a screen. p9p makes limited sense over SSH.)

The importance of Plan 9 for the heritage of Go is well known. :)
seninha
Long time nixers
(16-09-2022, 08:10 AM)josuah Wrote: Small tip: the most critical information that is missing from any default shell, in a portable way: the last command error code.

You can also use the builtin `trap` on the special signal `ERR` to run a command on error :
Code:
trap 'echo "$?"' ERR
This will print the error code of the last non-zero returning command right after it terminates and before the next prompt.

I use that, however, with some coloring and a "EXIT: " prefix:
Code:
trap 'printf "\e[1;31mEXIT: %s\e[0m\n" "$?"' ERR
tool
Registered
PD KSH v5.2.14 99/07/13.2