madlambda / nash

Nash stands for Nash shell.
Apache License 2.0
153 stars 10 forks source link

language: quote command paths #129

Open i4ki opened 7 years ago

i4ki commented 7 years ago

On every POSIX shell, the code below is valid:

"/home/user/some path with spaces/bin/cat" /etc/hosts

To invoke full path names with spaces. Nash doesn't supports it... I dislike the idea, but this broke lots of scripts embed into common unix softwares...

katcipis commented 7 years ago

The idea is to support quoted strings that are filepaths that have spaces inside them ? If this is not supported right now how would I handle it ? Escaping the spaces ?

i4ki commented 7 years ago

there's no way...

katcipis commented 7 years ago

hmm that does not sound good =/

i4ki commented 7 years ago

WHY you have spaces in your file names???

hahaha

You can make a hack:

λ> ln "/home/i4k/path with spaces.sh" /home/i4k/path-awesome.sh
λ> /home/i4k/path-awesome.sh

Well, it's not impossible ... kkk

katcipis commented 7 years ago

I dont, but sometimes I download stuff from the internet that does :-)

geyslan commented 7 years ago

Nowadays bash is using single quotation for spaced names by default. I have recollections of using backslash for that, but these days I have been induced to use single quotes since tools like ls and rm show me spaced file names just like that.

$ touch "test a"
$ ls test*
'test a'
$ rm "test a"
removed 'test a'
$ touch 'test b'
$ rm 'test b'
removed 'test b'

Backslashes still work, but quotes are much easier. By the way the bash completion works for any type of spaced naming (backslashed and single or double quoted).

I would like to see nash doing that one way only.

i4ki commented 7 years ago

@geyslan The issue is related to quote the "command path". The examples you show works with nash, the problem is: how to execute a file called "some thing.sh".

I have bad feelings about this, because if the code below is valid:

λ> "/home/i4k/Area de trabalho/test b.sh" param1 param2

Then the following should be valid too:

λ> $cmd param1 param2

because any location a literal string is valid, this string could be replaced by a variable in the specification. The command path/name from a string is ok, but from a variable is very bad for readability. Evaluating $cmd will execute what? rm? ...

This will be supported in some way, but we need to think more about it.

geyslan commented 7 years ago

@tiago4orion I got it. Spaced command paths can exist, so as you said it's a requisite. But it seems that you want to force literals usage avoiding variables as commands. It'll be harsh.

i4ki commented 7 years ago

Maybe we should open another issue to discuss evaluating commands in variables.

@geyslan But I don't get the idea of this and I really never used... I'd looked in your bash scripts and found this pattern. For example (from xrasengan):

awk=$(which awk 2> /dev/null)
who=$(which who 2> /dev/null)
unxrandr=$(which unxrandr 2> /dev/null)
notifier=$(which notify-send 2> /dev/null)
...

pids=$(ps u | $awk "/$tty/ { print \$2 }")
# and so on

What's the advantage over:

set -e

which awk who unxrandr notify-send 1>/dev/null
...
# awk is safe to exists
pids=$(ps u | awk "/$tty/ { print \$2 }")

In case of nash script, the code above should be:

which awk who unxrandr notify-send >[1=]
...
# awk is safe to exists
pids <= ps u | awk "/"+$tty+"/ { print $2 }"

There are other use cases other than that?

geyslan commented 7 years ago

@tiago4orion I got your point in using only a which and abort on error. However in xrasengan I just used variables like that for later checking as you can see here. xrasengan code is far from be reusable, I know it. That usage could be simplified using a check function. :sweat_smile:

Concerning set -e, I just avoided it since bash is an arcane beast ready to make my life a hell. As we can read in own bash manual:

This builtin is so complicated that it deserves its own section. ... -e Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), a list (see Lists), or a compound command (see Compound Commands) returns a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits.

This option applies to the shell environment and each subshell environment separately (see Command Execution Environment), and may cause subshells to exit before executing all the commands in the subshell.

If a compound command or shell function executes in a context where -e is being ignored, none of the commands executed within the compound command or function body will be affected by the -e setting, even if -e is set and a command returns a failure status. If a compound command or shell function sets -e while executing in a context where -e is ignored, that setting will not have any effect until the compound command or the command containing the function call completes.

There is a lot of ifs about what will happen when my command succeed or doesn't. So that can be a huge mess.

There are other use cases other than that?

Well, yeah, it would depend on how nash can be expandable and what control error methodology it can provide to the user. But expansion can make things to break. Perhaps the best is just teaching the user how to properly use nash.

Maybe we should open another issue to discuss evaluating commands in variables.

Agree.

i4ki commented 7 years ago

There is a lot of ifs about what will happen when my command succeed or doesn't. So that can be a huge mess.

It's terrible.. I agree.

In nash, you can customize the error message asking nash to not abort in error (prefixing command name/path with '-'):

-which awk >[1=] >[2=]

if $status != "0" {
        notify $ARGS[0] + " uses awk. Please, install it"
        abort
}