I just had the same problem (again) and finally came up with the following command macro that takes care of the shell's piping symbol, even in more difficult situations as below
macro cmd_cmd(expr)
pipemask = "--__|__--"
@show expr
expr = replace(expr, "\\r" => "\r", "\\n" => "\n", "\\t" => "\t", "'|'" => pipemask, "\"|\"" => pipemask)
ex = Base.shell_parse(expr)[1]
inds = findall(==(:(("|",))), ex.args)
push!(pushfirst!(inds, 0), length(ex.args) + 1)
exprs = []
for i in 1:length(inds) - 1
args = replace(ex.args[inds[i]+1:inds[i+1]-1], :(($pipemask,)) => :(("|",)))
x = Expr(:call, :(Base.cmd_gen), Expr(:tuple, args...))
push!(exprs, x)
end
Expr(:call, :pipeline, exprs...)
end
read(cmd`echo 'hello\nhello | world\nhello world' | grep '|'`, String)
# "hello | world\n"