Feature #16688
openAllow #to_path object as argument to system()
Description
I often work with Pathname objects, but when passing them to a system command I find it a bit tedious that they have to be explicitly converted to a String.
file = BASE + "config.json"
system(@cmd, file) #=> TypeError (no implicit conversion of Pathname into String)
system(@cmd, file.to_s) #=> works
I propose that the system/exec/spawn family of methods should try to convert their arguments using to_path
, if to_str
fails. I believe it makes perfect sense, since commandline arguments are so often pathnames.
This includes in/out redirection. system("ls", out: Pathname.new("file"))
should be valid.
Updated by zverok (Victor Shepelev) over 4 years ago
I always wondered, why Pathname
doesn't define to_str
?.. It seems to be a perfectly suitable option: implicit conversion for "specialized" variety of the String
, and it will make all non-Pathname-aware code work as expected... What are the downsides?
Updated by Dan0042 (Daniel DeLorme) over 4 years ago
I don't know the downsides, just that Pathname#to_str
was specifically removed 10 years ago: #1970
So I imagine there were some design considerations there...
Updated by shevegen (Robert A. Heiler) over 4 years ago
I do not have a strong opinion either way; I myself sort of just use Dir[]
rather than Pathname
(I just love Dir['*.rb']
and things like that), so I would
not need pathname anyway. But I can understand the argument given - 10 years is
also quite a long time ago, and the linked issue actually then refers to a commit
from matz in 2004, so 16 years ago. That's a long time.
I would recommend to focus primarily on #to_path
rather than a #to_str
, if only
for the purpose of the suggestion here; and perhaps suggest it for an upcoming
developer meeting, if this is wanted by Daniel, such as for
https://bugs.ruby-lang.org/issues/16661.
Updated by Eregon (Benoit Daloze) over 4 years ago
+1, this would be useful and the lack of it caused a few bugs when moving some code to using Pathname
.
Updated by dsisnero (Dominic Sisneros) over 4 years ago
I think what would be useful is when interpolating Path like objects (to_path
) that the path objects are shell escaped or cmd escaped when used with system()
or other cmd running objects. There are always errors on windows with directories or files with spaces. I like how Julia language deals with these in shell commands- they automatically escape the strings and expand the arrays but if we can't do that, I do agree with this proposal.
Updated by akr (Akira Tanaka) over 4 years ago
I'm positive.
It would be useful for most options for spawn
.
(except open mode, "w" of system("ls", out: ["/tmp/foo", "w"])
)
Updated by matz (Yukihiro Matsumoto) over 4 years ago
Accepted.
Matz.
Updated by mame (Yusuke Endoh) over 4 years ago
I'd like to confirm: system(Pathname("cat /etc/passwd"))
should attempt to execute a file whose path is ./cat\ /etc/passwd
, not attempt to show the content of /etc/passwd
, right?
Updated by Eregon (Benoit Daloze) over 4 years ago
mame (Yusuke Endoh) wrote in #note-9:
I'd like to confirm:
system(Pathname("cat /etc/passwd"))
should attempt to execute a file whose path is./cat\ /etc/passwd
, not attempt to show the content of/etc/passwd
, right?
Definitely the first, we should take advantage that we know it's supposed to be a path and a not a command line with spaces.
The second would be waiting to become a security vulnerability.
Updated by Dan0042 (Daniel DeLorme) over 4 years ago
There's maybe just one small gotcha to consider:
o = File.open("o","w")
system("ls", out: o) #should be equivalent
system("ls", out: o.fileno) #to this
system("ls", out: o.to_path) #not to this