# Shellescape

**URL:** <https://www.ruby-forum.com/t/shellescape/114226>\
**Category:** Development\
**Created:** [September 10, 2007, 8:10am UTC](https://www.ruby-forum.com/t/shellescape/114226 "2007-09-10T08:10:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Akinori\_MUSHA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b782af/32.png) [@Akinori\_MUSHA](https://www.ruby-forum.com/u/Akinori_MUSHA)\
**Post date:** [September 10, 2007, 8:10am UTC](https://www.ruby-forum.com/t/shellescape/114226/1 "2007-09-10T08:10:59Z")

</div>

ã€€shellwords.rb ã« shellescape() ç­‰ã‚’è¿½åŠ ã—ã‚ˆã†ã¨æ€ã„ã¾ã™ã€‚

ã€€ç†ç”±ã¨ã—ã¦ã¯ã€ system(), open(“|…”), IO.popen() ç­‰ã§ã‚³ãƒžãƒ³ãƒ‰  
ãƒ©ã‚¤ãƒ³ã‚’è¨˜è¿°ã™ã‚‹éš›ã€ãƒ¡ã‚¿æ–‡å­—ç­‰ã‚’ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã™ã‚‹é©å½“ãªé–¢æ•°ãŒæ¨™æº–ã§  
æä¾›ã•ã‚Œã¦ã„ãªã„ãŸã‚ã§ã™ã€‚

ã€€ä»•æ§˜ã¨ã—ã¦ã¯ã€Bourneã‚·ã‚§ãƒ«ã«æ¸¡ã™ã“ã¨ã‚’æƒ³å®šã—ã€å®‰å…¨ã§ãªã„æ–‡å­—ã‚’  
ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥()ã§ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã—ã¾ã™ã€‚æ–‡å­—åˆ—ã¯ã‚·ãƒ³ã‚°ãƒ«ãƒã‚¤ãƒˆåˆ—  
ã¨ã—ã¦æ‰±ã„ã¾ã™ã€‚ç†ç”±ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™ã€‚

- shellwords ã¯ãã‚‚ãã‚‚Bourneã‚·ã‚§ãƒ«(POSIX)ã®æ–‡æ³•ã«å‰‡ã£ãŸå‡¦ç†ã‚’è¡Œã†  
é–¢æ•°ã‚’æä¾›ã™ã‚‹ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã§ã‚ã‚‹ã€‚

- (Plan9ã®) rc ç­‰ã‚’å«ã‚å¤šãã®ã‚·ã‚§ãƒ«ã§ä½¿ãˆã‚‹ã®ãŒæœ›ã¾ã—ã„ã¨ã„ã†å£°ã‚‚  
[ruby-list:30049] ç­‰ã§å‡ºãŸã€‚ã—ã‹ã—ã€Bourneã‚·ã‚§ãƒ«ã¨ rc ã§ã¯å¼•ç”¨ç¬¦  
(')ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã®ä»•æ–¹ã«äº’æ›æ€§ãŒãªãã€ Windows ã® cmd.exe ã‚‚å¤‰æ•°  
å±•é–‹ã‚„å¼•ç”¨ç¬¦ã®æ‰±ã„ã®å·®ç•°ãŒå¤§ããã€ã²ã¨ã¤ã§å…¨å¯¾å¿œã™ã‚‹ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—  
æ–¹æ³•ãŒãªã„ã€‚

- å¼•ç”¨ç¬¦(‘)ã§æ‹¬ã‚‹æ–¹å¼ã ã¨ã€æ„Ÿå˜†ç¬¦(!)ã®æ‰±ã„ã®å·®ç•°ã®ãŸã‚ (t)csh ã§  
ä½¿ãˆãªããªã£ã¦ã—ã¾ã†ã€‚ã¾ãŸã€ãƒžãƒ«ãƒãƒã‚¤ãƒˆæ–‡å­—ã®ä¸­ã«å¼•ç”¨ç¬¦(’)ãŒ  
ã‚ã£ãŸå ´åˆã€ãƒžãƒ«ãƒãƒã‚¤ãƒˆå¯¾å¿œã®ã‚·ã‚§ãƒ«ã§ ‘…’'‘…’ ãŒèª¤è§£é‡ˆ  
ã•ã‚Œã‚‹å¯èƒ½æ€§ãŒé«˜ã„ã€‚

- äºŒé‡å¼•ç”¨ç¬¦(")ã§æ‹¬ã‚‹æ–¹å¼ã ã¨ã€ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥()ã®æ‰±ã„ã®å·®ç•°ã®  
ãŸã‚ (t)csh ã§ä½¿ãˆãªããªã£ã¦ã—ã¾ã†ã€‚

ã€€ãƒ‘ãƒƒãƒã‚’æ·»ä»˜ã—ã¾ã—ãŸã€‚ä»¥ä¸‹ãŒã‚µãƒžãƒªãƒ¼ã§ã™ã€‚

- Shellwords.shellescape ã‚’è¿½åŠ :  
Bourneã‚·ã‚§ãƒ«ã«è§£é‡ˆã•ã‚Œã‚‹å¯èƒ½æ€§ã®ã‚ã‚‹æ–‡å­—ã‚’ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã—ã¦è¿”ã™  
(ä»•æ§˜ã¯å®Ÿè£…ãŠã‚ˆã³ã‚³ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã®ã“ã¨)

- Shellwords.shelljoin ã‚’è¿½åŠ :  
ä¸Žãˆã‚‰ã‚ŒãŸå¼•æ•°åˆ—ã‹ã‚‰ã€Bourneã‚·ã‚§ãƒ«ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³æ–‡å­—åˆ—ã‚’ç”Ÿæˆ  
ã—ã¦è¿”ã™ (shellescape ã‚’åˆ©ç”¨)

- Shellwords.shellwords ã®åˆ¥å shellsplit ã‚’å®šç¾©

- åˆ©ç”¨ã®ä¾¿ã®ãŸã‚ String ã‚„ Array ã«ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã‚’è¿½åŠ

ã€€cmd.exe ã‚„ rc ã®å¯¾å¿œã«ã¤ã„ã¦ã¯ã€å°†æ¥çš„ã«ã‚ªãƒ—ã‚·ãƒ§ãƒ³å¼•æ•°ã‚’è¿½åŠ ã—ã€  
ãƒ—ãƒ©ãƒƒãƒˆãƒ•ã‚©ãƒ¼ãƒ ã”ã¨ã«å¦¥å½“ãªãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã‚’è¨­å®šã™ã‚‹ã“ã¨ã§å¯¾å¿œã§ã  
ã‚Œã°ã¨æ€ã„ã¾ã™ã€‚

–  
/  
/\_\_ \_\_ [Akinori.org](http://Akinori.org) / [MUSHA.org](http://MUSHA.org)  
/ ) ) ) ) / [FreeBSD.org](http://FreeBSD.org) / [Ruby-lang.org](http://Ruby-lang.org)  
Akinori MUSHA aka / (\_ / ( (\_\_( @ [iDaemons.org](http://iDaemons.org) / and.or.jp

“Different eyes see different things,  
Different hearts beat on different strings –  
But there are times for you and me when all such things agree”

# Index: shellwords.rb

— shellwords.rb (revision 13420)  
+++ shellwords.rb (working copy)  
@@ -1,29 +1,31 @@

# 

-# shellwords.rb: Split text into an array of tokens a la UNIX shell  
+# shellwords.rb: Manipulates strings a la UNIX Bourne shell

# 

# 

-# This module is originally a port of shellwords.pl, but modified to  
-# conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).  
+# This module manipulates strings according to the word parsing rules  
+# of the UNIX Bourne shell.

# 

-# Examples:  
+# The shellwords() function was originally a port of shellwords.pl,  
+# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).

# 

-# require ‘shellwords’  
-# words = Shellwords.shellwords(line)  
-#  
-# or  
-#  
-# require ‘shellwords’  
-# include Shellwords  
-# words = shellwords(line)  
+# Authors:  
+# - Wakou Aoyama  
+# - Akinori MUSHA [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

# 

module Shellwords

# 

- 
# Split text into an array of tokens in the same way the UNIX Bourne
- 
# shell does.

- 
# Splits a string into an array of tokens in the same way the UNIX
- 
# Bourne shell does.
- 
# 
- 
# argv = Shellwords.shellwords(‘here are “two words”’)
- 
# argv #=\> [“here”, “are”, “two words”]

# 

- 
# See the +Shellwords+ module documentation for an example.

- 
# +String#shellwords+ is a shorthand for this function.
- 
# 
- 
# argv = ‘here are “two words”’.shellwords
- 
# argv #=\> [“here”, “are”, “two words”]

# 
def shellwords(line)  
words = []  
@@ -39,6 +41,98 @@  
end  
words  
end
- alias shellsplit shellwords
- 
- 
# 
- 
# Escapes a string so that it can be safely used in a Bourne shell
- 
# command line.
- 
# 
- 
# Note that a resulted string should be used unquoted and is not
- 
# intended for use in double quotes nor in single quotes.
- 
# 
- 
# open(“| grep #{Shellwords.shellescape(pattern)} file”) { |pipe|
- 
# # …
- 
# }
- 
# 
- 
# +String#shellescape+ is a shorthand for this function.
- 
# 
- 
# open(“| grep #{pattern.shellescape} file”) { |pipe|
- 
# # …
- 
# }
- 
# 
- def shellescape(str)
- 
# An empty argument will be skipped, so return empty quotes.
- return “‘’” if str.empty?
- 
- str = str.dup
- 
- 
# Process as a single byte sequence because not all shell
- 
# implementations are multibyte aware.
- str.gsub!(/([^A-Za-z0-9\_-.,:/@\n])/n, “\\\1”)
- 
- 
# A LF cannot be escaped with a backslash because a backslash + LF
- 
# combo is regarded as line continuation and simply ignored.
- str.gsub!(/\n/, “‘\n’”)
- 
- return str
- end
- 
- 
# 
- 
# Builds a command line string from an argument list +array+ joining
- 
# all elements escaped for Bourne shell and separated by a space.
- 
# 
- 
# open(‘|’ + Shellwords.shelljoin([‘grep’, pattern, \*files])) {

|pipe|

- 
# # …
- 
# }
- 
# 
- 
# +Array#shelljoin+ is a shorthand for this function.
- 
# 
- 
# open(‘|’ + [‘grep’, pattern, \*files].shelljoin) { |pipe|
- 
# # …
- 
# }
- 
# 
- def shelljoin(array)
- array.map { |arg| shellescape(arg) }.join(’ ')
- end
- 
- module\_function :shellwords, :shellsplit, :shellescape, :shelljoin  
+end
- 

+class String

- 
# 
- 
# call-seq:
- 
# str.shellwords =\> array
- 
# 
- 
# Splits +str+ into an array of tokens in the same way the UNIX
- 
# Bourne shell does. See +Shellwords::shellwords+ for details.
- 
# 
- def shellwords
- Shellwords.shellwords(self)
- end
- alias shellsplit shellwords

- module\_function :shellwords

- 
# 
- 
# call-seq:
- 
# str.shellescape =\> string
- 
# 
- 
# Escapes +str+ so that it can be safely used in a Bourne shell
- 
# command line. See +Shellwords::shellescape+ for details.
- 
# 
- def shellescape
- Shellwords.shellescape(self)
- end  
+end
- 

+class Array

- 
# 
- 
# call-seq:
- 
# array.shelljoin =\> string
- 
# 
- 
# Builds a command line string from an argument list +array+ joining
- 
# all elements escaped for Bourne shell and separated by a space.
- 
# See +Shellwords::shelljoin+ for details.
- 
# 
- def shelljoin
- Shellwords.shelljoin(self)
- end  
end

---

<div class="post-metadata">

**Author:** ![Akinori\_MUSHA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b782af/32.png) [@Akinori\_MUSHA](https://www.ruby-forum.com/u/Akinori_MUSHA)\
**Post date:** [September 10, 2007, 9:03am UTC](https://www.ruby-forum.com/t/shellescape/114226/2 "2007-09-10T09:03:08Z")

</div>

e$B$J$+$@$G$9!#e(B

At Mon, 10 Sep 2007 15:10:13 +0900,  
Akinori MUSHA wrote in [ruby-dev:31768]:

> - Shellwords.shellescape e$B$rDI2Ce(B:  
> Bournee$B%7%’%k$K2r\<a$5$l$k2DG=@-$N$"$kJ8;z$r%(%9%1!\<%W$7$FJV$9e(B  
> (e$B;EMM$O\<BAu$\*$h$S%3%a%s%H$r;2\>H$N$3$He(B)
> 
> - Shellwords.shelljoin e$B$rDI2Ce(B:  
> e$BM?$($i$l$?0z?tNs$+$i!"e(BBournee$B%7%’%k%3%^%s%I%i%$%sJ8;zNs$r@8@.e(B  
> e$B$7$FJV$9e(B (shellescape e$B$rMxMQe(B)
> 
> - Shellwords.shellwords e$B$NJLL\>e(B shellsplit e$B$rDj5Ae(B

e$B%b%8%e!\<%k4X?t$K4X$9$k8B$j!"e(Bshelle$B$H$$$&e(Bprefixe$B$O$J$/$F$b$$$$$s$8$ce(B  
e$B$J$$$+$H;W$&$N$G$9$,!"e(BShellwords.escapee$B$de(BShellwords.join,  
Shellwords.splite$B$J$I$G$O$^$:$$$G$7$g$&$+!#e(B

---

<div class="post-metadata">

**Author:** ![Akinori\_MUSHA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b782af/32.png) [@Akinori\_MUSHA](https://www.ruby-forum.com/u/Akinori_MUSHA)\
**Post date:** [September 10, 2007, 9:14am UTC](https://www.ruby-forum.com/t/shellescape/114226/3 "2007-09-10T09:14:08Z")

</div>

At Mon, 10 Sep 2007 16:01:47 +0900,  
Nobuyoshi N. wrote:

> > - Shellwords.shellwords ã®åˆ¥å shellsplit ã‚’å®šç¾©
> 
> ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«é–¢æ•°ã«é–¢ã™ã‚‹é™ã‚Šã€shellã¨ã„ã†prefixã¯ãªãã¦ã‚‚ã„ã„ã‚“ã˜ã‚ƒ  
> ãªã„ã‹ã¨æ€ã†ã®ã§ã™ãŒã€Shellwords.escapeã‚„Shellwords.join,  
> Shellwords.splitãªã©ã§ã¯ã¾ãšã„ã§ã—ã‚‡ã†ã‹ã€‚

ã€€ç§ã‚‚ãã†æ€ã„ã¾ã—ãŸã€‚ã—ã‹ã—ã€ç¾è¡Œã®ã‚µãƒ³ãƒ—ãƒ«ã§ include Shellwords  
ã™ã‚‹ç”¨ä¾‹ãŒè¼‰ã£ã¦ã„ã‚‹ãŸã‚ã€ãã‚Œã‚’è¸è¥²ã—ãŸã‚³ãƒ¼ãƒ‰ãŒåå‰ç©ºé–“ã®æ±šæŸ“ã§  
å‹•ã‹ãªããªã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚(ç‰¹ã« split)

ã€€included() ã‚’å®šç¾©ã—ã¦é•·ã„åå‰ã®æ–¹ã ã‘è½ã¨ã™ã¨ã„ã†æ‰‹æ®µã¯ã‚ã‚‹ã‹ã‚‚  
ã—ã‚Œã¾ã›ã‚“ãŒâ€¦ã€‚

–  
/  
/\_\_ \_\_ [Akinori.org](http://Akinori.org) / [MUSHA.org](http://MUSHA.org)  
/ ) ) ) ) / [FreeBSD.org](http://FreeBSD.org) / [Ruby-lang.org](http://Ruby-lang.org)  
Akinori MUSHA aka / (\_ / ( (\_\_( @ [iDaemons.org](http://iDaemons.org) / and.or.jp

“Different eyes see different things,  
Different hearts beat on different strings –  
But there are times for you and me when all such things agree”

---

<div class="post-metadata">

**Author:** ![Akinori\_MUSHA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b782af/32.png) [@Akinori\_MUSHA](https://www.ruby-forum.com/u/Akinori_MUSHA)\
**Post date:** [September 10, 2007, 11:30am UTC](https://www.ruby-forum.com/t/shellescape/114226/4 "2007-09-10T11:30:23Z")

</div>

At Mon, 10 Sep 2007 17:29:08 +0900,  
Nobuyoshi N. wrote:

> > ã€€included() ã‚’å®šç¾©ã—ã¦é•·ã„åå‰ã®æ–¹ã ã‘è½ã¨ã™ã¨ã„ã†æ‰‹æ®µã¯ã‚ã‚‹ã‹ã‚‚  
> > ã—ã‚Œã¾ã›ã‚“ãŒâ€¦ã€‚
> 
> ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã¯é•·ã„ã‚‚ã®ã ã‘ã§ã„ã„ã¨æ€ã„ã¾ã™ã€‚ç‰¹ç•°ãƒ¡ã‚½ãƒƒãƒ‰  
> ã®æ–¹ã ã‘aliasã™ã‚Œã°ã„ã„ã®ã§ã¯ã€‚

ã€€ãã†ã‹ã€‚include ã§é™ã‚Šã¦ãã‚‹ã®ã¯ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã®æ–¹ã ã€‚  
æŽ¡ç”¨ã—ã¾ã™ã€‚

> ã•ã™ãŒã«wordsã¯å˜ç‹¬ã§ã¯æ„å‘³ä¸æ˜Žãªã®ã§ã„ã‚‰ãªã„ã¨æ€ã„ã¾ã™ã€‚

ã€€ãƒ¡ã‚½ãƒƒãƒ‰åã¨ã—ã¦ã® shellwords() ã¯ã„ã¾ã„ã¡ã§ã™ã‚ˆã­ã€‚  
shellsplit ã‚’æœ¬åã«ã—ã¦ shellwords ã¯åˆ¥åã«æ ¼ä¸‹ã’ã™ã‚‹ã‹ã€‚

–  
/  
/\_\_ \_\_ [Akinori.org](http://Akinori.org) / [MUSHA.org](http://MUSHA.org)  
/ ) ) ) ) / [FreeBSD.org](http://FreeBSD.org) / [Ruby-lang.org](http://Ruby-lang.org)  
Akinori MUSHA aka / (\_ / ( (\_\_( @ [iDaemons.org](http://iDaemons.org) / and.or.jp

“Different eyes see different things,  
Different hearts beat on different strings –  
But there are times for you and me when all such things agree”

---

<div class="post-metadata">

**Author:** ![Akinori\_MUSHA](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/b782af/32.png) [@Akinori\_MUSHA](https://www.ruby-forum.com/u/Akinori_MUSHA)\
**Post date:** [September 10, 2007, 10:30am UTC](https://www.ruby-forum.com/t/shellescape/114226/5 "2007-09-10T10:30:17Z")

</div>

e$B$J$+$@$G$9!#e(B

At Mon, 10 Sep 2007 16:12:58 +0900,  
Akinori MUSHA wrote in [ruby-dev:31770]:

> > e$B%b%8%e!\<%k4X?t$K4X$9$k8B$j!"e(Bshelle$B$H$$$&e(Bprefixe$B$O$J$/$F$b$$$$$s$8$ce(B  
> > e$B$J$$$+$H;W$&$N$G$9$,!"e(BShellwords.escapee$B$de(BShellwords.join,  
> > Shellwords.splite$B$J$I$G$O$^$:$$$G$7$g$&$+!#e(B
> 
> e$B!!;d$b$=$&;W$$$^$7$?!#$7$+$7!“8=9T$N%5%s%W%k$Ge(B include Shellwords  
> e$B$9$kMQNc$,:$C$F$$$k$?$a!”$=$l$rF’=1$7$?%3!\<%I$,L\>A06u4V$N1x@w$Ge(B  
> e$BF0$+$J$/$J$k2DG=@-$,$"$j$^$9!#e(B(e$BFC$Ke(B split)
> 
> e$B!!e(Bincluded() e$B$rDj5A$7$FD9$$L\>A0$NJ}$@$1Mn$H$9$H$$$&\<jCJ$O$"$k$+$be(B  
> e$B$7$l$^$;$s$,!D!#e(B

e$B%$%s%9%?%s%9%a%=%C%I$OD9$$$b$N$@$1$G$$$$$H;W$$$^$9!#FC0[%a%=%C%Ie(B  
e$B$NJ}$@$1e(Baliase$B$9$l$P$$$$$N$G$O!#e(B

module Shellwords  
module\_function :shellwords, :shellsplit, :shellescape, :shelljoin

```
class << self
  alias split shellsplit
  alias escape shellescape
  alias join shelljoin
end

```

end

e$B$5$9$,$Ke(Bwordse$B$OC1FH$G$O0UL#ITL@$J$N$G$$$i$J$$$H;W$$$^$9!#e(B
