shellwords 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/test.yml +24 -0
- data/.gitignore +8 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +46 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/shellwords.rb +240 -0
- data/shellwords.gemspec +22 -0
- metadata +56 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: de57cbc9a6fe3cf8c17e930e43f602c3bc7a0166b22dac8f9135a51bf8d8ef7a
|
4
|
+
data.tar.gz: b9cd1182e3b09befea06b84c5a75407a4a1d4d008d1a0ac8fd9c32804f4cb046
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f1ef0d09c787850785c82ad87b591a59788ffa97bf29d740079d80702e432dd50718ba8bb811637602600eedd38c037b913bdc08eb0deecc98bbc2140caf119c
|
7
|
+
data.tar.gz: 72e8753f7f9b851c8373771beb450e628a48ea549476c8877a94e1e2859142cbf626a6c73dc73a6ac9a0f98b5a7bda26a4a127eb1086eb3f8921c53bd08cd5a0
|
@@ -0,0 +1,24 @@
|
|
1
|
+
name: test
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
ruby: [ 2.7, 2.6, 2.5, head ]
|
11
|
+
os: [ ubuntu-latest, macos-latest ]
|
12
|
+
runs-on: ${{ matrix.os }}
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@master
|
15
|
+
- name: Set up Ruby
|
16
|
+
uses: ruby/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
ruby-version: ${{ matrix.ruby }}
|
19
|
+
- name: Install dependencies
|
20
|
+
run: |
|
21
|
+
gem install bundler --no-document
|
22
|
+
bundle install
|
23
|
+
- name: Run test
|
24
|
+
run: rake test
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
|
+
SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Shellwords
|
2
|
+
|
3
|
+
This module manipulates strings according to the word parsing rules
|
4
|
+
of the UNIX Bourne shell.
|
5
|
+
|
6
|
+
The shellwords() function was originally a port of shellwords.pl,
|
7
|
+
but modified to conform to the Shell & Utilities volume of the IEEE
|
8
|
+
Std 1003.1-2008, 2016 Edition [1].
|
9
|
+
|
10
|
+
[1] [IEEE Std 1003.1-2008, 2016 Edition, the Shell & Utilities volume](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html)
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'shellwords'
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle install
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install shellwords
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'shellwords'
|
32
|
+
|
33
|
+
argv = Shellwords.split('three blind "mice"')
|
34
|
+
argv #=> ["three", "blind", "mice"]
|
35
|
+
```
|
36
|
+
|
37
|
+
## Development
|
38
|
+
|
39
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
40
|
+
|
41
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
42
|
+
|
43
|
+
## Contributing
|
44
|
+
|
45
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/shellwords.
|
46
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "shellwords"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/shellwords.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
##
|
3
|
+
# == Manipulates strings like the UNIX Bourne shell
|
4
|
+
#
|
5
|
+
# This module manipulates strings according to the word parsing rules
|
6
|
+
# of the UNIX Bourne shell.
|
7
|
+
#
|
8
|
+
# The shellwords() function was originally a port of shellwords.pl,
|
9
|
+
# but modified to conform to the Shell & Utilities volume of the IEEE
|
10
|
+
# Std 1003.1-2008, 2016 Edition [1].
|
11
|
+
#
|
12
|
+
# === Usage
|
13
|
+
#
|
14
|
+
# You can use Shellwords to parse a string into a Bourne shell friendly Array.
|
15
|
+
#
|
16
|
+
# require 'shellwords'
|
17
|
+
#
|
18
|
+
# argv = Shellwords.split('three blind "mice"')
|
19
|
+
# argv #=> ["three", "blind", "mice"]
|
20
|
+
#
|
21
|
+
# Once you've required Shellwords, you can use the #split alias
|
22
|
+
# String#shellsplit.
|
23
|
+
#
|
24
|
+
# argv = "see how they run".shellsplit
|
25
|
+
# argv #=> ["see", "how", "they", "run"]
|
26
|
+
#
|
27
|
+
# They treat quotes as special characters, so an unmatched quote will
|
28
|
+
# cause an ArgumentError.
|
29
|
+
#
|
30
|
+
# argv = "they all ran after the farmer's wife".shellsplit
|
31
|
+
# #=> ArgumentError: Unmatched quote: ...
|
32
|
+
#
|
33
|
+
# Shellwords also provides methods that do the opposite.
|
34
|
+
# Shellwords.escape, or its alias, String#shellescape, escapes
|
35
|
+
# shell metacharacters in a string for use in a command line.
|
36
|
+
#
|
37
|
+
# filename = "special's.txt"
|
38
|
+
#
|
39
|
+
# system("cat -- #{filename.shellescape}")
|
40
|
+
# # runs "cat -- special\\'s.txt"
|
41
|
+
#
|
42
|
+
# Note the '--'. Without it, cat(1) will treat the following argument
|
43
|
+
# as a command line option if it starts with '-'. It is guaranteed
|
44
|
+
# that Shellwords.escape converts a string to a form that a Bourne
|
45
|
+
# shell will parse back to the original string, but it is the
|
46
|
+
# programmer's responsibility to make sure that passing an arbitrary
|
47
|
+
# argument to a command does no harm.
|
48
|
+
#
|
49
|
+
# Shellwords also comes with a core extension for Array, Array#shelljoin.
|
50
|
+
#
|
51
|
+
# dir = "Funny GIFs"
|
52
|
+
# argv = %W[ls -lta -- #{dir}]
|
53
|
+
# system(argv.shelljoin + " | less")
|
54
|
+
# # runs "ls -lta -- Funny\\ GIFs | less"
|
55
|
+
#
|
56
|
+
# You can use this method to build a complete command line out of an
|
57
|
+
# array of arguments.
|
58
|
+
#
|
59
|
+
# === Authors
|
60
|
+
# * Wakou Aoyama
|
61
|
+
# * Akinori MUSHA <knu@iDaemons.org>
|
62
|
+
#
|
63
|
+
# === Contact
|
64
|
+
# * Akinori MUSHA <knu@iDaemons.org> (current maintainer)
|
65
|
+
#
|
66
|
+
# === Resources
|
67
|
+
#
|
68
|
+
# 1: {IEEE Std 1003.1-2008, 2016 Edition, the Shell & Utilities volume}[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html]
|
69
|
+
|
70
|
+
module Shellwords
|
71
|
+
# Splits a string into an array of tokens in the same way the UNIX
|
72
|
+
# Bourne shell does.
|
73
|
+
#
|
74
|
+
# argv = Shellwords.split('here are "two words"')
|
75
|
+
# argv #=> ["here", "are", "two words"]
|
76
|
+
#
|
77
|
+
# Note, however, that this is not a command line parser. Shell
|
78
|
+
# metacharacters except for the single and double quotes and
|
79
|
+
# backslash are not treated as such.
|
80
|
+
#
|
81
|
+
# argv = Shellwords.split('ruby my_prog.rb | less')
|
82
|
+
# argv #=> ["ruby", "my_prog.rb", "|", "less"]
|
83
|
+
#
|
84
|
+
# String#shellsplit is a shortcut for this function.
|
85
|
+
#
|
86
|
+
# argv = 'here are "two words"'.shellsplit
|
87
|
+
# argv #=> ["here", "are", "two words"]
|
88
|
+
def shellsplit(line)
|
89
|
+
words = []
|
90
|
+
field = String.new
|
91
|
+
line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
|
92
|
+
|word, sq, dq, esc, garbage, sep|
|
93
|
+
raise ArgumentError, "Unmatched quote: #{line.inspect}" if garbage
|
94
|
+
# 2.2.3 Double-Quotes:
|
95
|
+
#
|
96
|
+
# The <backslash> shall retain its special meaning as an
|
97
|
+
# escape character only when followed by one of the following
|
98
|
+
# characters when considered special:
|
99
|
+
#
|
100
|
+
# $ ` " \ <newline>
|
101
|
+
field << (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1'))
|
102
|
+
if sep
|
103
|
+
words << field
|
104
|
+
field = String.new
|
105
|
+
end
|
106
|
+
end
|
107
|
+
words
|
108
|
+
end
|
109
|
+
|
110
|
+
alias shellwords shellsplit
|
111
|
+
|
112
|
+
module_function :shellsplit, :shellwords
|
113
|
+
|
114
|
+
class << self
|
115
|
+
alias split shellsplit
|
116
|
+
end
|
117
|
+
|
118
|
+
# Escapes a string so that it can be safely used in a Bourne shell
|
119
|
+
# command line. +str+ can be a non-string object that responds to
|
120
|
+
# +to_s+.
|
121
|
+
#
|
122
|
+
# Note that a resulted string should be used unquoted and is not
|
123
|
+
# intended for use in double quotes nor in single quotes.
|
124
|
+
#
|
125
|
+
# argv = Shellwords.escape("It's better to give than to receive")
|
126
|
+
# argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
|
127
|
+
#
|
128
|
+
# String#shellescape is a shorthand for this function.
|
129
|
+
#
|
130
|
+
# argv = "It's better to give than to receive".shellescape
|
131
|
+
# argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
|
132
|
+
#
|
133
|
+
# # Search files in lib for method definitions
|
134
|
+
# pattern = "^[ \t]*def "
|
135
|
+
# open("| grep -Ern -e #{pattern.shellescape} lib") { |grep|
|
136
|
+
# grep.each_line { |line|
|
137
|
+
# file, lineno, matched_line = line.split(':', 3)
|
138
|
+
# # ...
|
139
|
+
# }
|
140
|
+
# }
|
141
|
+
#
|
142
|
+
# It is the caller's responsibility to encode the string in the right
|
143
|
+
# encoding for the shell environment where this string is used.
|
144
|
+
#
|
145
|
+
# Multibyte characters are treated as multibyte characters, not as bytes.
|
146
|
+
#
|
147
|
+
# Returns an empty quoted String if +str+ has a length of zero.
|
148
|
+
def shellescape(str)
|
149
|
+
str = str.to_s
|
150
|
+
|
151
|
+
# An empty argument will be skipped, so return empty quotes.
|
152
|
+
return "''".dup if str.empty?
|
153
|
+
|
154
|
+
str = str.dup
|
155
|
+
|
156
|
+
# Treat multibyte characters as is. It is the caller's responsibility
|
157
|
+
# to encode the string in the right encoding for the shell
|
158
|
+
# environment.
|
159
|
+
str.gsub!(/[^A-Za-z0-9_\-.,:+\/@\n]/, "\\\\\\&")
|
160
|
+
|
161
|
+
# A LF cannot be escaped with a backslash because a backslash + LF
|
162
|
+
# combo is regarded as a line continuation and simply ignored.
|
163
|
+
str.gsub!(/\n/, "'\n'")
|
164
|
+
|
165
|
+
return str
|
166
|
+
end
|
167
|
+
|
168
|
+
module_function :shellescape
|
169
|
+
|
170
|
+
class << self
|
171
|
+
alias escape shellescape
|
172
|
+
end
|
173
|
+
|
174
|
+
# Builds a command line string from an argument list, +array+.
|
175
|
+
#
|
176
|
+
# All elements are joined into a single string with fields separated by a
|
177
|
+
# space, where each element is escaped for the Bourne shell and stringified
|
178
|
+
# using +to_s+.
|
179
|
+
#
|
180
|
+
# ary = ["There's", "a", "time", "and", "place", "for", "everything"]
|
181
|
+
# argv = Shellwords.join(ary)
|
182
|
+
# argv #=> "There\\'s a time and place for everything"
|
183
|
+
#
|
184
|
+
# Array#shelljoin is a shortcut for this function.
|
185
|
+
#
|
186
|
+
# ary = ["Don't", "rock", "the", "boat"]
|
187
|
+
# argv = ary.shelljoin
|
188
|
+
# argv #=> "Don\\'t rock the boat"
|
189
|
+
#
|
190
|
+
# You can also mix non-string objects in the elements as allowed in Array#join.
|
191
|
+
#
|
192
|
+
# output = `#{['ps', '-p', $$].shelljoin}`
|
193
|
+
#
|
194
|
+
def shelljoin(array)
|
195
|
+
array.map { |arg| shellescape(arg) }.join(' ')
|
196
|
+
end
|
197
|
+
|
198
|
+
module_function :shelljoin
|
199
|
+
|
200
|
+
class << self
|
201
|
+
alias join shelljoin
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class String
|
206
|
+
# call-seq:
|
207
|
+
# str.shellsplit => array
|
208
|
+
#
|
209
|
+
# Splits +str+ into an array of tokens in the same way the UNIX
|
210
|
+
# Bourne shell does.
|
211
|
+
#
|
212
|
+
# See Shellwords.shellsplit for details.
|
213
|
+
def shellsplit
|
214
|
+
Shellwords.split(self)
|
215
|
+
end
|
216
|
+
|
217
|
+
# call-seq:
|
218
|
+
# str.shellescape => string
|
219
|
+
#
|
220
|
+
# Escapes +str+ so that it can be safely used in a Bourne shell
|
221
|
+
# command line.
|
222
|
+
#
|
223
|
+
# See Shellwords.shellescape for details.
|
224
|
+
def shellescape
|
225
|
+
Shellwords.escape(self)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
class Array
|
230
|
+
# call-seq:
|
231
|
+
# array.shelljoin => string
|
232
|
+
#
|
233
|
+
# Builds a command line string from an argument list +array+ joining
|
234
|
+
# all elements escaped for the Bourne shell and separated by a space.
|
235
|
+
#
|
236
|
+
# See Shellwords.shelljoin for details.
|
237
|
+
def shelljoin
|
238
|
+
Shellwords.join(self)
|
239
|
+
end
|
240
|
+
end
|
data/shellwords.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "shellwords"
|
3
|
+
spec.version = "0.1.0"
|
4
|
+
spec.authors = ["Akinori MUSHA"]
|
5
|
+
spec.email = ["knu@idaemons.org"]
|
6
|
+
|
7
|
+
spec.summary = %q{Manipulates strings with word parsing rules of UNIX Bourne shell.}
|
8
|
+
spec.description = %q{Manipulates strings with word parsing rules of UNIX Bourne shell.}
|
9
|
+
spec.homepage = "https://github.com/ruby/shellwords"
|
10
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
11
|
+
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
12
|
+
|
13
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
14
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
15
|
+
|
16
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shellwords
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Akinori MUSHA
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-09-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Manipulates strings with word parsing rules of UNIX Bourne shell.
|
14
|
+
email:
|
15
|
+
- knu@idaemons.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".github/workflows/test.yml"
|
21
|
+
- ".gitignore"
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- bin/console
|
27
|
+
- bin/setup
|
28
|
+
- lib/shellwords.rb
|
29
|
+
- shellwords.gemspec
|
30
|
+
homepage: https://github.com/ruby/shellwords
|
31
|
+
licenses:
|
32
|
+
- Ruby
|
33
|
+
- BSD-2-Clause
|
34
|
+
metadata:
|
35
|
+
homepage_uri: https://github.com/ruby/shellwords
|
36
|
+
source_code_uri: https://github.com/ruby/shellwords
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.3.0
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubygems_version: 3.1.2
|
53
|
+
signing_key:
|
54
|
+
specification_version: 4
|
55
|
+
summary: Manipulates strings with word parsing rules of UNIX Bourne shell.
|
56
|
+
test_files: []
|