# A small package to run string as shell command

**URL:** https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163
**Category:** General Usage
**Tags:** package, shell
**Created:** [September 30, 2017, 8:36am UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163 "2017-09-30T08:36:32Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![innerlee](https://avatars.discourse-cdn.com/v4/letter/i/b19c9b/32.png) [@innerlee](https://discourse.julialang.org/u/innerlee)
#### Post date: [September 30, 2017, 8:36am UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/1 "2017-09-30T08:36:32Z")

</div>

Building a string is easy, but building a `Cmd` is always a headache to me. So I write a [small package](https://github.com/innerlee/Shell.jl) to run strings as `Cmd`.

Here is the task that drives me to write the package: There are some sub-folders containing `.png` files. I want to convert them into videos and place these videos at the root folder. And here is the code

```julia
julia> using Shell

julia> for (r,d,f) in walkdir(".")
           if any(x->endswith(x, ".png"), f)
               run("convert $r/*.png $(basename(r)).mp4")
           end
       end

```

It is more intuitive than dealing `Cmd` objects (In fact, I still not able to write the correct `Cmd` for this task…). Hope this will help someone.

* * *

edit:  
It also supports windows.

```julia
julia> using Shell

julia> run("dir")

... (some output)

julia> useshell("powershell")
"powershell"

julia> run("ls")

... (some output)

```

**WARN** :  
as `@yuyichao` pointed out below, there are something wrong with the code. And I quote it here

> Blockquote
> 
> 1. The package is doing type piracy, don’t extend Base.run.
> 2. Please put a warning in the README to that people are **NOT** encouraged to write buggy code as what you show above.

---

<div class="post-metadata">

### Author: ![Evizero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evizero/32/10118_2.png) [@Evizero](https://discourse.julialang.org/u/Evizero)
#### Post date: [September 30, 2017, 9:29am UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/2 "2017-09-30T09:29:31Z")

</div>

I also run into this kind of problem regularly

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [September 30, 2017, 12:12pm UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/3 "2017-09-30T12:12:54Z")

</div>

1. The package is doing type piracy, don’t extend `Base.run`.
2. Please put a warning in the README to that people are **NOT** encouraged to write buggy code as what you show above.

---

<div class="post-metadata">

### Author: ![innerlee](https://avatars.discourse-cdn.com/v4/letter/i/b19c9b/32.png) [@innerlee](https://discourse.julialang.org/u/innerlee)
#### Post date: [September 30, 2017, 12:23pm UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/4 "2017-09-30T12:23:56Z")

</div>

Thanks for the suggestion

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 30, 2017, 1:01pm UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/5 "2017-09-30T13:01:55Z")

</div>

> [@innerlee](#):
>
> `run("convert $r/*.png $(basename(r)).mp4")`

Note that doing this sort of thing has all of the problems that @StefanKarpinski described in his [Shelling Out Sucks](https://julialang.org/blog/2012/03/shelling-out-sucks) blog post. It will have unexpected results if `basename(r)` contains spaces, for example. (Maybe this is what @yuyichao was referring to with “buggy code”.) That’s why it would be better to learn to use `Cmd` objects.

The main thing that can’t be done directly with `Cmd` objects in this example is the `*.png` globbing ([implement more special shell-like functionality in backticks · Issue #20401 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/20401)). However, you can use the [Glob.jl](https://github.com/vtjnash/Glob.jl) package for that:

```julia
using Glob
run(`convert $(glob("*.png", r)) $(basename(r)).mp4`)

```

---

<div class="post-metadata">

### Author: ![innerlee](https://avatars.discourse-cdn.com/v4/letter/i/b19c9b/32.png) [@innerlee](https://discourse.julialang.org/u/innerlee)
#### Post date: [September 30, 2017, 1:44pm UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/6 "2017-09-30T13:44:22Z")

</div>

Didn’t know `Glob.jl` can be used like this. Thanks for the tip!

---

<div class="post-metadata">

### Author: ![innerlee](https://avatars.discourse-cdn.com/v4/letter/i/b19c9b/32.png) [@innerlee](https://discourse.julialang.org/u/innerlee)
#### Post date: [October 1, 2017, 1:27pm UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/7 "2017-10-01T13:27:40Z")

</div>

I updated the code to address the problems mentioned in the comments. One is type piracy, and the other is the escaping of spaces. It might be buggy for complex jobs, but it is handy to run simple commands at my skill level.

After writting these codes, I start to wonder, maybe the default way (`Cmd` and `Pipelines`) is more concise…

---

<div class="post-metadata">

### Author: ![NightMachinary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nightmachinary/32/14196_2.png) [@NightMachinary](https://discourse.julialang.org/u/NightMachinary)
#### Post date: [April 27, 2020, 6:49pm UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/8 "2020-04-27T18:49:23Z")

</div>

Does this fork a new shell for each command?

---

<div class="post-metadata">

### Author: ![innerlee](https://avatars.discourse-cdn.com/v4/letter/i/b19c9b/32.png) [@innerlee](https://discourse.julialang.org/u/innerlee)
#### Post date: [April 28, 2020, 12:17am UTC](https://discourse.julialang.org/t/a-small-package-to-run-string-as-shell-command/6163/9 "2020-04-28T00:17:11Z")

</div>

Basically it saves commands into a tmpfile.sh and run it by sh tmptile.sh
