module Shellwords
Manipuliert Strings wie die UNIX Bourne Shell
Dieses Modul manipuliert Strings gemäß den Wortanalyse-Regeln der UNIX Bourne Shell.
Die Funktion shellwords() war ursprünglich ein Port von shellwords.pl, wurde aber modifiziert, um mit dem Shell & Utilities Band des IEEE Std 1003.1-2008, 2016 Edition konform zu sein.
Verwendung
Sie können Shellwords verwenden, um einen String in ein für die Bourne Shell freundliches Array zu parsen.
require 'shellwords' argv = Shellwords.split('three blind "mice"') argv #=> ["three", "blind", "mice"]
Sobald Sie Shellwords require'd haben, können Sie den Alias split String#shellsplit verwenden.
argv = "see how they run".shellsplit argv #=> ["see", "how", "they", "run"]
Sie behandeln Anführungszeichen als Sonderzeichen, sodass ein nicht übereinstimmendes Anführungszeichen einen ArgumentError verursacht.
argv = "they all ran after the farmer's wife".shellsplit #=> ArgumentError: Unmatched quote: ...
Shellwords bietet auch Methoden, die das Gegenteil tun. Shellwords.escape, oder sein Alias String#shellescape, maskiert Shell-Metazeichen in einem String für die Verwendung in einer Befehlszeile.
filename = "special's.txt" system("cat -- #{filename.shellescape}") # runs "cat -- special\\'s.txt"
Beachten Sie das „–“. Ohne es würde cat(1) das folgende Argument als Befehlszeilenoption behandeln, wenn es mit „-“ beginnt. Es ist garantiert, dass Shellwords.escape einen String in eine Form konvertiert, die eine Bourne Shell wieder in den ursprünglichen String parst, aber es liegt in der Verantwortung des Programmierers sicherzustellen, dass die Übergabe eines beliebigen Arguments an einen Befehl keinen Schaden anrichtet.
Shellwords kommt auch mit einer Core-Erweiterung für Array, Array#shelljoin.
dir = "Funny GIFs" argv = %W[ls -lta -- #{dir}] system(argv.shelljoin + " | less") # runs "ls -lta -- Funny\\ GIFs | less"
Sie können diese Methode verwenden, um eine vollständige Befehlszeile aus einem Array von Argumenten zu erstellen.
Autoren
-
Wakou Aoyama
-
Akinori MUSHA <knu@iDaemons.org>
Kontakt
-
Akinori MUSHA <knu@iDaemons.org> (aktueller Betreuer)
Constants
- VERSION
-
Der Versionsnummernstring.
Öffentliche Klassenmethoden
Source
# File lib/shellwords.rb, line 158 def shellescape(str) str = str.to_s # An empty argument will be skipped, so return empty quotes. return "''".dup if str.empty? # Shellwords cannot contain NUL characters. raise ArgumentError, "NUL character" if str.index("\0") str = str.dup # Treat multibyte characters as is. It is the caller's responsibility # to encode the string in the right encoding for the shell # environment. str.gsub!(/[^A-Za-z0-9_\-.,:+\/@\n]/, "\\\\\\&") # A LF cannot be escaped with a backslash because a backslash + LF # combo is regarded as a line continuation and simply ignored. str.gsub!(/\n/, "'\n'") return str end
Maskiert einen String, damit er sicher in einer Bourne-Shell-Befehlszeile verwendet werden kann. str kann ein Nicht-String-Objekt sein, das auf to_s reagiert.
str darf wegen der Natur des exec-Systemaufrufs keine NUL-Zeichen enthalten.
Beachten Sie, dass ein resultierender String ungequotet verwendet werden sollte und nicht zur Verwendung in doppelten oder einfachen Anführungszeichen bestimmt ist.
argv = Shellwords.escape("It's better to give than to receive") argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
String#shellescape ist eine Kurzform für diese Funktion.
argv = "It's better to give than to receive".shellescape argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive" # Search files in lib for method definitions pattern = "^[ \t]*def " open("| grep -Ern -e #{pattern.shellescape} lib") { |grep| grep.each_line { |line| file, lineno, matched_line = line.split(':', 3) # ... } }
Es liegt in der Verantwortung des Aufrufers, den String in der richtigen Kodierung für die Shell-Umgebung zu kodieren, in der dieser String verwendet wird.
Mehrbyte-Zeichen werden als Mehrbyte-Zeichen behandelt, nicht als Bytes.
Gibt einen leeren, quoteten String zurück, wenn str eine Länge von Null hat.
Source
# File lib/shellwords.rb, line 208 def shelljoin(array) array.map { |arg| shellescape(arg) }.join(' ') end
Erstellt einen Befehlszeilenstring aus einer Argumentliste, array.
Alle Elemente werden zu einem einzigen String zusammengefügt, wobei Felder durch ein Leerzeichen getrennt sind, wobei jedes Element für die Bourne Shell maskiert und mit to_s stringifiziert wird. Siehe auch Shellwords.shellescape.
ary = ["There's", "a", "time", "and", "place", "for", "everything"] argv = Shellwords.join(ary) argv #=> "There\\'s a time and place for everything"
Array#shelljoin ist eine Abkürzung für diese Funktion.
ary = ["Don't", "rock", "the", "boat"] argv = ary.shelljoin argv #=> "Don\\'t rock the boat"
Sie können auch Nicht-String-Objekte in den Elementen mischen, wie es in Array#join erlaubt ist.
output = `#{['ps', '-p', $$].shelljoin}`
Source
# File lib/shellwords.rb, line 90 def shellsplit(line) words = [] field = String.new line.scan(/\G\s*(?>([^\0\s\\\'\"]+)|'([^\0\']*)'|"((?:[^\0\"\\]|\\[^\0])*)"|(\\[^\0]?)|(\S))(\s|\z)?/m) do |word, sq, dq, esc, garbage, sep| if garbage b = $~.begin(0) line = $~[0] line = "..." + line if b > 0 raise ArgumentError, "#{garbage == "\0" ? 'Nul character' : 'Unmatched quote'} at #{b}: #{line}" end # 2.2.3 Double-Quotes: # # The <backslash> shall retain its special meaning as an # escape character only when followed by one of the following # characters when considered special: # # $ ` " \ <newline> field << (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1')) if sep words << field field = String.new end end words end
Teilt einen String in ein Array von Tokens auf die gleiche Weise, wie es die UNIX Bourne Shell tut.
argv = Shellwords.split('here are "two words"') argv #=> ["here", "are", "two words"]
line darf wegen der Natur des exec-Systemaufrufs keine NUL-Zeichen enthalten.
Beachten Sie jedoch, dass dies kein Befehlszeilen-Parser ist. Shell-Metazeichen mit Ausnahme von einfachen und doppelten Anführungszeichen sowie Backslash werden nicht als solche behandelt.
argv = Shellwords.split('ruby my_prog.rb | less') argv #=> ["ruby", "my_prog.rb", "|", "less"]
String#shellsplit ist eine Kurzform für diese Funktion.
argv = 'here are "two words"'.shellsplit argv #=> ["here", "are", "two words"]
Private Instanzmethoden
Source
# File lib/shellwords.rb, line 158 def shellescape(str) str = str.to_s # An empty argument will be skipped, so return empty quotes. return "''".dup if str.empty? # Shellwords cannot contain NUL characters. raise ArgumentError, "NUL character" if str.index("\0") str = str.dup # Treat multibyte characters as is. It is the caller's responsibility # to encode the string in the right encoding for the shell # environment. str.gsub!(/[^A-Za-z0-9_\-.,:+\/@\n]/, "\\\\\\&") # A LF cannot be escaped with a backslash because a backslash + LF # combo is regarded as a line continuation and simply ignored. str.gsub!(/\n/, "'\n'") return str end
Maskiert einen String, damit er sicher in einer Bourne-Shell-Befehlszeile verwendet werden kann. str kann ein Nicht-String-Objekt sein, das auf to_s reagiert.
str darf wegen der Natur des exec-Systemaufrufs keine NUL-Zeichen enthalten.
Beachten Sie, dass ein resultierender String ungequotet verwendet werden sollte und nicht zur Verwendung in doppelten oder einfachen Anführungszeichen bestimmt ist.
argv = Shellwords.escape("It's better to give than to receive") argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
String#shellescape ist eine Kurzform für diese Funktion.
argv = "It's better to give than to receive".shellescape argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive" # Search files in lib for method definitions pattern = "^[ \t]*def " open("| grep -Ern -e #{pattern.shellescape} lib") { |grep| grep.each_line { |line| file, lineno, matched_line = line.split(':', 3) # ... } }
Es liegt in der Verantwortung des Aufrufers, den String in der richtigen Kodierung für die Shell-Umgebung zu kodieren, in der dieser String verwendet wird.
Mehrbyte-Zeichen werden als Mehrbyte-Zeichen behandelt, nicht als Bytes.
Gibt einen leeren, quoteten String zurück, wenn str eine Länge von Null hat.
Source
# File lib/shellwords.rb, line 208 def shelljoin(array) array.map { |arg| shellescape(arg) }.join(' ') end
Erstellt einen Befehlszeilenstring aus einer Argumentliste, array.
Alle Elemente werden zu einem einzigen String zusammengefügt, wobei Felder durch ein Leerzeichen getrennt sind, wobei jedes Element für die Bourne Shell maskiert und mit to_s stringifiziert wird. Siehe auch Shellwords.shellescape.
ary = ["There's", "a", "time", "and", "place", "for", "everything"] argv = Shellwords.join(ary) argv #=> "There\\'s a time and place for everything"
Array#shelljoin ist eine Abkürzung für diese Funktion.
ary = ["Don't", "rock", "the", "boat"] argv = ary.shelljoin argv #=> "Don\\'t rock the boat"
Sie können auch Nicht-String-Objekte in den Elementen mischen, wie es in Array#join erlaubt ist.
output = `#{['ps', '-p', $$].shelljoin}`
Source
# File lib/shellwords.rb, line 90 def shellsplit(line) words = [] field = String.new line.scan(/\G\s*(?>([^\0\s\\\'\"]+)|'([^\0\']*)'|"((?:[^\0\"\\]|\\[^\0])*)"|(\\[^\0]?)|(\S))(\s|\z)?/m) do |word, sq, dq, esc, garbage, sep| if garbage b = $~.begin(0) line = $~[0] line = "..." + line if b > 0 raise ArgumentError, "#{garbage == "\0" ? 'Nul character' : 'Unmatched quote'} at #{b}: #{line}" end # 2.2.3 Double-Quotes: # # The <backslash> shall retain its special meaning as an # escape character only when followed by one of the following # characters when considered special: # # $ ` " \ <newline> field << (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1')) if sep words << field field = String.new end end words end
Teilt einen String in ein Array von Tokens auf die gleiche Weise, wie es die UNIX Bourne Shell tut.
argv = Shellwords.split('here are "two words"') argv #=> ["here", "are", "two words"]
line darf wegen der Natur des exec-Systemaufrufs keine NUL-Zeichen enthalten.
Beachten Sie jedoch, dass dies kein Befehlszeilen-Parser ist. Shell-Metazeichen mit Ausnahme von einfachen und doppelten Anführungszeichen sowie Backslash werden nicht als solche behandelt.
argv = Shellwords.split('ruby my_prog.rb | less') argv #=> ["ruby", "my_prog.rb", "|", "less"]
String#shellsplit ist eine Kurzform für diese Funktion.
argv = 'here are "two words"'.shellsplit argv #=> ["here", "are", "two words"]