Skip to content

Use awk for reliable path stripping #1360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 29, 2021
Merged

Conversation

umireon
Copy link
Contributor

@umireon umireon commented Dec 23, 2016

nvm_strip_path() will fail if NVM_DIR contains meta characters such as #*.^$[]\.

$ NVM_DIR='/#'
$ echo "${NVM_DIR}/1/bin:${NVM_DIR}/2/bin:${NVM_DIR}/3/bin:/usr/bin" | sed \
  -e "s#${NVM_DIR}/[^/]*/bin[^:]*:##g" \
  -e "s#:${NVM_DIR}/[^/]*/bin[^:]*##g" \
  -e "s#${NVM_DIR}/[^/]*/bin[^:]*##g"

sed: 1: "s#/#/[^/]*/bin[^:]*:##g
": bad flag in substitute command: '#'

awk is capable to solve this problem.

$ NVM_DIR='/#*.^$[]'
$ printf %s "${NVM_DIR}/1/bin:${NVM_DIR}/2/bin:${NVM_DIR}/3/bin:/usr/bin" |
  awk -v NVM_DIR="${NVM_DIR}" -v RS=: '
  index($0, NVM_DIR) == 1 {
    path = substr($0, length(NVM_DIR) + 1)
    if (path ~ "^/[^/]*'"${2-}"'.*$") { next }
  }
  { print }' | paste -s -d: -

/usr/bin

Verified

This commit was signed with the committer’s verified signature.
ljharb Jordan Harband
This works with paths which contains regex meta characters.
@ljharb
Copy link
Member

ljharb commented Dec 23, 2016

Are those characters even valid in a PATH?

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add tests that would have failed without your change?

Also, what is paste? Is it part of POSIX?

@umireon
Copy link
Contributor Author

umireon commented Dec 23, 2016

Are those characters even valid in a PATH?

According to SUS, there seems to be no restriction in PATH other than :, which is the path separator, and at least they worked on my environment (macOS).

Also, what is paste? Is it part of POSIX?

paste -s -d: - is a part of POSIX.

Can you add tests that would have failed without your change?

Yes, I will.

@umireon
Copy link
Contributor Author

umireon commented Dec 23, 2016

A new test was added.
I also noticed that handling backslash like \+ needs an additional work to escape backslash:

awk -v NVM_DIR="$(echo ${NVM_DIR} | sed -e 's/\\/\\\\/g')" -v RS=: '

but I am not sure this should be included.

@ljharb
Copy link
Member

ljharb commented Dec 23, 2016

If it's legal in $PATH, we might as well support it here.

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

Is this PR still valid?

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

@umireon yep! there's an unrelated test failure; i'll rebase this again after fixing it.

@ljharb ljharb closed this Sep 29, 2021
@ljharb ljharb reopened this Sep 29, 2021
@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

I don't remember this PR much. I'm surprised that this PR is still valid🤣 It was 5 years ago!

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

life comes at you fast :-p sorry it took me so long to get back to it.

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

'printf' should be command printf

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

The quotation trick is to avoid alias, the same as backslash trick.

a() {
  echo test
}

alias a=false

'a' # test

This is for functions, not for built-ins.

At that time, I misunderstood something.

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

ah thanks, i never knew about the quotation trick, but since we use command everywhere, might as well stick to that :-)

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

For example, command nvm_has will not work so that we should do \nvm_has or 'nvm_has'.
Or not considering alias because it is prefixed by nvm_.

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

indeed, i don't protect against that for anything that clearly belongs to nvm :-)

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

Maybe 'command' awk if you consider alias command=something🤔

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

There are too many possibilities in sourced shell scripts😭

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

yeah true :-) if someone has aliased command everything will break, so ¯\_(ツ)_/¯

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

I learned how I use the if clause from this nvm project.
Error handling in shell scripts is so hard.

I'm not sure the awk command never fails.

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

If tests are passing, we'll ship it, and if it fails, we'll get bug reports.

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

There are some complicated awk scripts so there seem to be practices about awk in this project, thus it's OK.

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

When I created this PR, nvm only has simple awk scripts as far as I remember, but I worry too much for now. Dismiss my comments.

@umireon
Copy link
Contributor Author

umireon commented Sep 29, 2021

I think awk is the best command in POSIX specification.

@ljharb ljharb merged commit 53f9ba8 into nvm-sh:master Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants