Skip to content

Commit 23b04b8

Browse files
shell_(parse|split|escape): fix some issues with deprecation (#19985)
1 parent 7b7b4e1 commit 23b04b8

File tree

3 files changed

+26
-18
lines changed

3 files changed

+26
-18
lines changed

base/managers.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ function launch_on_machine(manager::SSHManager, machine, cnt, params, launched,
185185
cmd = `cd $dir '&&' $tval $exename $exeflags`
186186

187187
# shell login (-l) with string command (-c) to launch julia process
188-
cmd = `sh -l -c $(shell_escape(cmd, special = ""))`
188+
cmd = `sh -l -c $(shell_escape(cmd))`
189189

190190
# remote launch with ssh with given ssh flags / host / port information
191191
# -T → disable pseudo-terminal allocation
@@ -195,7 +195,7 @@ function launch_on_machine(manager::SSHManager, machine, cnt, params, launched,
195195
# forwarded connections are causing collisions
196196
# -n → Redirects stdin from /dev/null (actually, prevents reading from stdin).
197197
# Used when running ssh in the background.
198-
cmd = `ssh -T -a -x -o ClearAllForwardings=yes -n $sshflags $host $(shell_escape(cmd, special = ""))`
198+
cmd = `ssh -T -a -x -o ClearAllForwardings=yes -n $sshflags $host $(shell_escape(cmd))`
199199

200200
# launch the remote Julia process
201201

base/process.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,14 @@ end
9797
hash(x::AndCmds, h::UInt) = hash(x.a, hash(x.b, h))
9898
==(x::AndCmds, y::AndCmds) = x.a == y.a && x.b == y.b
9999

100-
shell_escape(cmd::Cmd; special::AbstractString=shell_special) =
100+
shell_escape(cmd::Cmd; special::AbstractString="") =
101101
shell_escape(cmd.exec..., special=special)
102102

103103
function show(io::IO, cmd::Cmd)
104104
print_env = cmd.env !== nothing
105105
print_dir = !isempty(cmd.dir)
106106
(print_env || print_dir) && print(io, "setenv(")
107-
esc = shell_escape(cmd)
107+
esc = shell_escape(cmd, special=shell_special)
108108
print(io, '`')
109109
for c in esc
110110
if c == '`'
@@ -797,7 +797,7 @@ function cmd_gen(parsed)
797797
end
798798

799799
macro cmd(str)
800-
return :(cmd_gen($(shell_parse(str)[1])))
800+
return :(cmd_gen($(shell_parse(str, special=shell_special)[1])))
801801
end
802802

803803
wait(x::Process) = if !process_exited(x); stream_wait(x, x.exitnotify); end

base/shell.jl

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44

55
const shell_special = "#{}()[]<>|&*?~;"
66

7-
function shell_parse(str::AbstractString, interpolate::Bool=true)
7+
# needs to be factored out so depwarn only warns once
8+
@noinline warn_shell_special(special) =
9+
depwarn("special characters \"$special\" should now be quoted in commands", :warn_shell_special)
10+
11+
function shell_parse(
12+
str::AbstractString,
13+
interpolate::Bool=true;
14+
special::AbstractString=""
15+
)
816
s = lstrip(str)
917
# strips the end but respects the space when the string ends with "\\ "
1018
r = RevString(s)
@@ -94,8 +102,8 @@ function shell_parse(str::AbstractString, interpolate::Bool=true)
94102
update_arg(s[i:j-1]); i = k
95103
c, k = next(s,k)
96104
end
97-
elseif !in_single_quotes && !in_double_quotes && c in shell_special
98-
depwarn("special characters \"$shell_special\" should now be quoted in commands", :shell_parse)
105+
elseif !in_single_quotes && !in_double_quotes && c in special
106+
warn_shell_special(special) # noinline depwarn
99107
end
100108
j = k
101109
end
@@ -118,15 +126,15 @@ function shell_parse(str::AbstractString, interpolate::Bool=true)
118126
end
119127

120128
function shell_split(s::AbstractString)
121-
parsed = shell_parse(s,false)[1]
129+
parsed = shell_parse(s, false)[1]
122130
args = AbstractString[]
123131
for arg in parsed
124132
push!(args, string(arg...))
125133
end
126134
args
127135
end
128136

129-
function print_shell_word(io::IO, word::AbstractString, special::AbstractString = shell_special)
137+
function print_shell_word(io::IO, word::AbstractString, special::AbstractString = "")
130138
if isempty(word)
131139
print(io, "''")
132140
end
@@ -158,30 +166,30 @@ end
158166

159167
function print_shell_escaped(
160168
io::IO, cmd::AbstractString, args::AbstractString...;
161-
special::AbstractString=shell_special
169+
special::AbstractString=""
162170
)
163171
print_shell_word(io, cmd, special)
164172
for arg in args
165173
print(io, ' ')
166174
print_shell_word(io, arg, special)
167175
end
168176
end
169-
print_shell_escaped(io::IO; special::String=shell_special) = nothing
177+
print_shell_escaped(io::IO; special::String="") = nothing
170178

171179
"""
172-
shell_escape(args::Union{Cmd,AbstractString...}; special::AbstractString="$shell_special")
180+
shell_escape(args::Union{Cmd,AbstractString...}; special::AbstractString="")
173181
174182
The unexported `shell_escape` function is the inverse of the unexported `shell_split` function:
175183
it takes a string or command object and escapes any special characters in such a way that calling
176184
`shell_split` on it would give back the array of words in the original command. The `special`
177185
keyword argument controls what characters in addition to whitespace, backslashes, quotes and
178-
dollar signs are considered to be special. Examples:
186+
dollar signs are considered to be special (default: none). Examples:
187+
188+
julia> Base.shell_escape("cat", "/foo/bar baz", "&&", "echo", "done")
189+
"cat '/foo/bar baz' && echo done"
179190
180191
julia> Base.shell_escape("echo", "this", "&&", "that")
181192
"echo this '&&' that"
182-
183-
julia> Base.shell_escape("cat", "/foo/bar baz", "&&", "echo", "done", special="")
184-
"cat '/foo/bar baz' && echo done"
185193
"""
186-
shell_escape(args::AbstractString...; special::AbstractString=shell_special) =
194+
shell_escape(args::AbstractString...; special::AbstractString="") =
187195
sprint(io->print_shell_escaped(io, args..., special=special))

0 commit comments

Comments
 (0)