Skip to main content
updates & clarifications
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1POSIXLY_CORRECT before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features later.

This does not address aliases though, so you must use \unset (or use some form of quoting/escaping on that word) to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

(while, do, done and [[ are reserved words and don't need precautions. You can't use = in an alias or function name, so no precautions needed for setting POSIXLY_CORRECT.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

Thanks to commenters below for the extra suggestions.

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

(while, do, done and [[ are reserved words and don't need precautions.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

Olivier D is almost correct, but you must set POSIXLY_CORRECT before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features later.

This does not address aliases though, so you must use \unset (or use some form of quoting/escaping on that word) to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

(while, do, done and [[ are reserved words and don't need precautions. You can't use = in an alias or function name, so no precautions needed for setting POSIXLY_CORRECT.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

Thanks to commenters below for the extra suggestions.

added 187 characters in body
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

For the paranoid, this should fix everything, I think:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

(while, do, done and [[ are reserved words and don't need precautions.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

A readonly POSIXLY_CORRECT is not a real problem, this is not a boolean or flag its presence enables POSIX mode, so if it exists as a readonly you can rely on POSIX features, even if the value is empty or 0. You'll simply need to unset problematic functions a different way than above, perhaps with some cut-and-paste:

\help -s "*" | while IFS=": " read cmd junk; do echo \\unset -f $cmd; done

(and ignore any errors) or engage in some other scriptobatics.


Other notes:

  • function is a reserved word, it can be aliased but not overridden with a function. (Aliasing function is mildly troublesome because \function is not acceptable as a way of bypassing it)
  • [[, ]] are reserved words, they can be aliased (which will be ignored) but not overridden with a function (though functions can be so named)
  • (( is not a valid name for a function, nor an alias

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

For the paranoid, this should fix everything, I think:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

(while, do, done and [[ are reserved words and don't need precautions.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

For the paranoid, this should fix everything, I think:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

(while, do, done and [[ are reserved words and don't need precautions.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

A readonly POSIXLY_CORRECT is not a real problem, this is not a boolean or flag its presence enables POSIX mode, so if it exists as a readonly you can rely on POSIX features, even if the value is empty or 0. You'll simply need to unset problematic functions a different way than above, perhaps with some cut-and-paste:

\help -s "*" | while IFS=": " read cmd junk; do echo \\unset -f $cmd; done

(and ignore any errors) or engage in some other scriptobatics.


Other notes:

  • function is a reserved word, it can be aliased but not overridden with a function. (Aliasing function is mildly troublesome because \function is not acceptable as a way of bypassing it)
  • [[, ]] are reserved words, they can be aliased (which will be ignored) but not overridden with a function (though functions can be so named)
  • (( is not a valid name for a function, nor an alias
added 187 characters in body
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

For the paranoid, this should fix everything, I think:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ ^([a-z]+):$re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

Note(while, do, done and [[ are reserved words and don't need precautions.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the protected functionsspecial builtins when POSIXLY_CORRECT is set.

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

For the paranoid, this should fix everything, I think:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
while \read cmd; do 
    [[ "$cmd" =~ ^([a-z]+): ]] && \unset ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner). You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the protected functions when POSIXLY_CORRECT is set.

Olivier D is almost correct, but you must set POSIXLY_CORRECT=1 before running unset. POSIX has a notion of Special Built-ins, and bash supports this. unset is one such builtin. Search for SPECIAL_BUILTIN in builtins/*.c in the bash source for a list, it includes set, unset, export, eval and source.

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

The rogue unset has now been removed from the environment, if you unset command, type, builtin then you should be able to proceed, but unset POSIXLY_CORRECT if you are relying on non-POSIX behaviour or advanced bash features.

This does not address aliases though, so you must use \unset to be sure it works in interactive shell (or always, in case expand_aliases is in effect).

For the paranoid, this should fix everything, I think:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

(while, do, done and [[ are reserved words and don't need precautions.) Note we are using unset -f to be sure to unset functions, although variables and functions share the same namespace it's possible for both to exist simultaneously (thanks to Etan Reisner) in which case unset-ing twice would also do the trick. You can mark a function readonly, bash does not prevent you unsetting a readonly function up to and including bash-4.2, bash-4.3 does prevent you but it still honours the special builtins when POSIXLY_CORRECT is set.

added 419 characters in body
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46
Loading
added 456 characters in body
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46
Loading
Source Link
mr.spuratic
  • 10.4k
  • 29
  • 46
Loading