# Way to make CLI in Julia?

**URL:** https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171
**Category:** General Usage
**Tags:** question
**Created:** [August 1, 2017, 7:18pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171 "2017-08-01T19:18:17Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 1, 2017, 7:18pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/1 "2017-08-01T19:18:17Z")

</div>

Let’s say I’ve been using the following alias:

```julia
alias julz="julia -L ~/.julia/v0.6/Julz/src/functions/utils/cli.jl -e 'cli()' --"

```

However I think this is a little hacky and want an actual bash cmd // like how python or npm would install it

How could I add a `deps/build.jl` file to make a bin executable (robustly across all systems)

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 1, 2017, 7:20pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/2 "2017-08-01T19:20:54Z")

</div>

also, the cli file in question is:

[https://github.com/djsegal/Julz.jl/blob/master/src/functions/utils/cli.jl](https://github.com/djsegal/Julz.jl/blob/master/src/functions/utils/cli.jl)

---

<div class="post-metadata">

### Author: ![Michael\_Eastwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michael_eastwood/32/669_2.png) [@Michael\_Eastwood](https://discourse.julialang.org/u/Michael_Eastwood)
#### Post date: [August 1, 2017, 8:38pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/3 "2017-08-01T20:38:35Z")

</div>

On linux you just need to put `#!/usr/bin/env julia` at the top of the file, run `chmod +x filename` and add it to the system path. I assume it’s similar for macs, but I have no idea for windows.

In your case you will also need to add the `cli()` function call to the file itself so that the file is a self-contained script.

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 1, 2017, 9:37pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/4 "2017-08-01T21:37:46Z")

</div>

Is there a way to automize this?

I’d prefer to not have people have to:

- run chmod on a file and
- add things to their `PATH` (in a bash profile)

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 1, 2017, 9:46pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/5 "2017-08-01T21:46:36Z")

</div>

> [@djsegal](#):
>
> I’d prefer to not have people have to:
> 
> run chmod on a file and  
> add things to their PATH (in a bash profile)

To me, these are safeguards that I would not want a package to override.

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 1, 2017, 9:48pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/6 "2017-08-01T21:48:49Z")

</div>

Do you have an idea around it?

If I do `brew install node`, I want to be able to use the `node` command from the terminal immediately

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 1, 2017, 9:53pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/7 "2017-08-01T21:53:24Z")

</div>

> [@djsegal](#):
>
> If I do brew install node, I want to be able to use the node command from the terminal immediately

Are you intending to provide this as a registered Julia package (via METADATA)? If so, that’s the key difference - I don’t expect `Pkg.install` or `Pkg.build` to do anything to my global environment, and I’d be TICKED if some package I installed started installing executables outside the environment or altering my path.

If this is intended to be installed via some other means, then you could do what homebrew does; namely, create a separate script and make that script download and chmod the file. Since `PATH` environments are widely different, there’s not a whole lot you can do about that except try to write things into `/usr/local/` somewhere.

---

<div class="post-metadata">

### Author: ![Michael\_Eastwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michael_eastwood/32/669_2.png) [@Michael\_Eastwood](https://discourse.julialang.org/u/Michael_Eastwood)
#### Post date: [August 1, 2017, 9:55pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/8 "2017-08-01T21:55:12Z")

</div>

What I had in mind was that most of those changes would be checked into git and wouldn’t run in your `build.jl`. The only thing that would happen in `build.jl` is that you invite the user to add a given directory to their path.

---

<div class="post-metadata">

### Author: ![Michael\_Eastwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michael_eastwood/32/669_2.png) [@Michael\_Eastwood](https://discourse.julialang.org/u/Michael_Eastwood)
#### Post date: [August 1, 2017, 9:58pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/9 "2017-08-01T21:58:15Z")

</div>

> [@anon94023334](#):
>
> I’d be TICKED if some package I installed started installing executables outside the environment

BinDeps already does this if you use, for example, apt to grab dependencies.

Edit: not arguing this is good behavior, just pointing out that it is actually common in the current package ecosystem

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 1, 2017, 10:03pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/10 "2017-08-01T22:03:09Z")

</div>

> [@Michael\_Eastwood](#):
>
> BinDeps already does this if you use, for example, apt to grab dependencies.

Right; my experience is primarily on OSX, which uses a “sandboxed” (not really, but different install root) version of homebrew.

Does this imply that you need root to install BinDeps packages on Linux?

---

<div class="post-metadata">

### Author: ![Michael\_Eastwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michael_eastwood/32/669_2.png) [@Michael\_Eastwood](https://discourse.julialang.org/u/Michael_Eastwood)
#### Post date: [August 1, 2017, 10:06pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/11 "2017-08-01T22:06:50Z")

</div>

> [@anon94023334](#):
>
> Does this imply that you need root to install BinDeps packages on Linux?

Sometimes yes, but the process of asking for the sudo password hasn’t worked for some time now…

> <https://github.com/JuliaPackaging/BinDeps.jl/issues/199>
>
> I've run into an odd problem with building packages with apt dependencies, in wh…ich the password prompt for the sudo apt-get fails. At the moment a simple workaround is just installing the packages manually, but I'm posting what I've got in case you guys can see an easy fix.
> 
> The problem occurs on Lubuntu 15.10, when running julia 0.4.2 (staticfloat ppa release) from a local LXterminal session. I've observed it on Cairo.jl (\[\_jl\_libcairo error with Gadfly + Cairo #124\](https://github.com/JuliaLang/Cairo.jl/issues/124#issuecomment-176607173) ) and HDF5.jl (see code block following).
> 
> \`\`\`
> julia\> Pkg.build("HDF5")
> INFO: Building Blosc
> INFO: Building HDF5
> Installing dependency hdf5-tools via \`sudo apt-get install hdf5-tools\`:
> sudo: no tty present and no askpass program specified
> ================================\[ERROR: HDF5 \]=================================
> 
> LoadError: failed process: Process(\`sudo apt-get install hdf5-tools\`, ProcessExited(1)) \[1\]
> while loading /home/mark/.julia/v0.4/HDF5/deps/build.jl, in expression starting on line 24
> 
> ================================================================================
> \`\`\`
> 
> Hope that's of some use. Let me know if you need any more logs etc. -- I know Lubuntu isn't a very common distro! Thanks.

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 1, 2017, 10:08pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/12 "2017-08-01T22:08:30Z")

</div>

I guess this means that, in general, any BinDeps-using package is going to be a no-go (or at least a bureaucratic hassle) on most HPCs that provide even a modicum of security.

---

<div class="post-metadata">

### Author: ![Michael\_Eastwood](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/michael_eastwood/32/669_2.png) [@Michael\_Eastwood](https://discourse.julialang.org/u/Michael_Eastwood)
#### Post date: [August 1, 2017, 10:13pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/13 "2017-08-01T22:13:59Z")

</div>

This is pretty off-topic, but if the package provides a “from source” build option, that doesn’t need root, but I believe the system package manager takes precedence. You need to manually comment-out the `provides(AptGet, ...)` line in `build.jl` if you want to prevent the package from preferring the system package manager.

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 3, 2017, 6:04pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/14 "2017-08-03T18:04:57Z")

</div>

Just following up on this, what’s the best way to distribute Julia CLI tools then?

This seems like a thing that more people are going to want over time

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 3, 2017, 6:18pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/15 "2017-08-03T18:18:37Z")

</div>

For \*nix, I’d suggest either installation instructions that include “download, chmod +x, move to directory in path”, or a shell script that does this that gets executed by whatever package manager / distribution mechanism that is used to install the tool.

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 3, 2017, 6:28pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/16 "2017-08-03T18:28:06Z")

</div>

It just seems like there should be an easier way.

Making a cli in python was one of the simplest things I ever did:

- [Building Simple Command Line Interfaces in Python](https://stormpath.com/blog/building-simple-cli-interfaces-in-python)

* * *

Also, users are a notoriously unfaithful bunch.

Each unusual step you give them leads to sizable acquisition drop-offs

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 3, 2017, 6:31pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/17 "2017-08-03T18:31:29Z")

</div>

I’m not quite sure what problem you’re trying to solve here, then. At some point in order to use a CLI tool one needs an executable to be installed in a place that the user can run it. It sounded to me like you didn’t have that, which is what my previous comment attempted to address.

This problem isn’t unique to Julia; it’s part of the installation process for _every_ downloaded executable ever.

If you could enumerate specifically what you’re trying to do, and what problems you’re running into, maybe we could help find a solution.

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 3, 2017, 6:37pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/18 "2017-08-03T18:37:51Z")

</div>

Summarizing:

- There is an existing CLI file that has an alias
  - `alias julz="julia -L ~/.julia/v0.6/Julz/src/functions/utils/cli.jl -e 'cli()' --"`

- In order to move from an alias to an executable, it needs to be distributed through something like `apt-get` or `brew`
- I’m unclear on how to package a Julia package in a format that would get approved by either of those projects (e.g. `brew`) where the executable is just that alias in a bash script

Are there other projects that have made Julia executables?

How do people deal with the need for people to have `Julia` and do a `Pkg.clone` before the script can be run?

* * *

I’m aware this problem is not unique to Julia.

I just don’t know how to accomplish it in as few steps as possible (without reinventing 10 wheels)

---

<div class="post-metadata">

### Author: ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)
#### Post date: [August 3, 2017, 6:48pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/19 "2017-08-03T18:48:56Z")

</div>

> In order to move from an alias to an executable, it needs to be distributed through something like apt-get or brew

Why do you need to do this at all? Is it easier for folks to type `apt-get install julz-cli` (or whatever you’re calling it, and then making sure you’ve got both `apt` and `brew` installers, and then that just handles folks who have ubuntu and osx with homebrew installed) than to type `curl -L https://mysite.com/install_tool.sh | bash` (where `install_tool.sh` does the lifting)?

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [August 3, 2017, 6:53pm UTC](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171/20 "2017-08-03T18:53:28Z")

</div>

This is getting close to the final answer.

I just don’t know how to make a debian package and submit it to apt-get.

If you make it a stand-alone project that just has:

```julia
julz () {
  julia -L ~/.julia/v0.6/Julz/src/functions/utils/cli.jl -e 'cli()' -- "$@"
}

```

Will it even get accepted?

* * *

Do you have any docs or existing Julia packages that do this?

[Next page](https://discourse.julialang.org/t/way-to-make-cli-in-julia/5171.md?page=2)
