Struct shell_quote::Bash

source ·
pub struct Bash;
Expand description

Quote byte strings for use with Bash, the GNU Bourne-Again Shell.

⚠️ Warning

It is possible to encode NUL in a Bash string, but Bash appears to then truncate the rest of the string after that point, likely because NUL is the C string terminator. This appears to be a bug in Bash or at least a serious limitation.

If you’re quoting UTF-8 content this may not be a problem since there is only one code point – the null character itself – that will ever produce a NUL byte. To avoid this problem entirely, consider using Modified UTF-8 so that the NUL byte can never appear in a valid byte stream.

Notes

From bash(1):

Words of the form $‘string’ are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:

\a     alert (bell)
\b     backspace
\e     an escape character
\f     form feed
\n     new line
\r     carriage return
\t     horizontal tab
\v     vertical tab
\\     backslash
\'     single quote
\nnn   the eight-bit character whose value is the
       octal value nnn (one to three digits)
\xHH   the eight-bit character whose value is the
       hexadecimal value HH (one or two hex digits)
\cx    a control-x character

Bash allows, in newer versions, for non-ASCII Unicode characters with \uHHHH and \UXXXXXXXX syntax inside these ANSI C quoted strings, but we avoid this and work only with bytes. Part of the problem is that it’s not clear how Bash then works with these strings. Does it encode these characters into bytes according to the user’s current locale? Are strings in Bash now natively Unicode?

For now it’s up to the caller to figure out encoding. 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 Bash

source

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:

See quote_into for a variant that extends an existing Vec instead of allocating a new one.

Examples
assert_eq!(Bash::quote("foobar"), b"foobar");
assert_eq!(Bash::quote("foo bar"), b"$'foo bar'");
source

pub fn quote_into<'a, S: ?Sized + Into<Quotable<'a>>>(s: S, sout: &mut Vec<u8>)

Quote a string of bytes into an existing Vec<u8>.

See quote for more details.

Examples
let mut buf = Vec::with_capacity(128);
Bash::quote_into("foobar", &mut buf);
buf.push(b' ');  // Add a space.
Bash::quote_into("foo bar", &mut buf);
assert_eq!(buf, b"foobar $'foo bar'");

Trait Implementations§

source§

impl Clone for Bash

source§

fn clone(&self) -> Bash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Bash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Bash

source§

impl Quoter for Bash

Auto Trait Implementations§

§

impl RefUnwindSafe for Bash

§

impl Send for Bash

§

impl Sync for Bash

§

impl Unpin for Bash

§

impl UnwindSafe for Bash

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.