Struct shell_quote::Sh
source · pub struct Sh;Expand description
Quote byte strings for use with /bin/sh.
§Notes
The following escapes seem to be “okay”:
\a alert (bell)
\b backspace
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\nnn the eight-bit character whose value is the octal value nnn
I wasn’t able to find any definitive statement of exactly how Bourne Shell
strings should be quoted, mainly because “Bourne Shell” or /bin/sh can
refer to many different pieces of software: Bash has a Bourne Shell mode,
/bin/sh on Ubuntu is actually Dash, and on macOS 12.3 (and later, and
possibly earlier) all bets are off:
shis a POSIX-compliant command interpreter (shell). It is implemented by re-execing as eitherbash(1),dash(1), orzsh(1)as determined by the symbolic link located at/private/var/select/sh. If/private/var/select/shdoes not exist or does not point to a valid shell,shwill use one of the supported shells.
⚠️ In practice, however, bytes between 0x80 and 0xff inclusive cannot be
escaped with \nnn notation. The shell simply ignores these escapes and
treats \nnn as a literal string of 4 characters. Hence, in this module,
these bytes are reproduced as-is within the quoted string output, with no
special escaping.
The code in this module sticks to escape sequences that I consider “standard” by a heuristic known only to me. It operates byte by byte, making no special allowances for multi-byte character sets. In other words, it’s up to the caller to figure out encoding for non-ASCII characters. A significant use case for this code is to quote filenames into scripts, and on *nix variants I understand that filenames are essentially arrays of bytes, even if the OS adds some normalisation and case-insensitivity on top.
If you have some expertise in this area I would love to hear from you.
Implementations§
source§impl Sh
impl Sh
sourcepub fn quote<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> ⓘ
pub fn quote<'a, S: ?Sized + Into<Quotable<'a>>>(s: S) -> Vec<u8> ⓘ
Quote a string of bytes into a new Vec<u8>.
This will return one of the following:
- The string as-is, if no quoting is necessary.
- A quoted string containing ANSI-C-like escapes, like
'foo\nbar'.
See quote_into for a variant that extends an
existing Vec instead of allocating a new one.
§Examples
assert_eq!(Sh::quote("foobar"), b"foobar");
assert_eq!(Sh::quote("foo bar"), b"'foo bar'");Trait Implementations§
Auto Trait Implementations§
impl Freeze for Sh
impl RefUnwindSafe for Sh
impl Send for Sh
impl Sync for Sh
impl Unpin for Sh
impl UnwindSafe for Sh
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)source§impl<T> CloneToUninit for Twhere
T: Copy,
impl<T> CloneToUninit for Twhere
T: Copy,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)