DEV Community

Cover image for Dotfiles - Shell Config
Michael Currin
Michael Currin

Posted on

Dotfiles - Shell Config

Content for Bash config ~/.bashrc or ZSH config ~/.zshrc

See my full Shell config file on GitHub.

OS flags

For any values in configs or aliases which are OS-specific, I found it useful to determine the OS with logic once-off and then reuse the flags.

IS_MAC=false IS_LINUX=false case "$(uname -s)" in Darwin*) IS_MAC=true ;; Linux*) IS_LINUX=true ;; esac 
Enter fullscreen mode Exit fullscreen mode

That lets me then use the variable to perform OS-specific behavior. Here I add a Brew-installed Ruby gems path to the PATH value, just for macOS.

if [[ "$IS_MAC" == 'true' ]]; then export PATH="/usr/local/opt/ruby/bin:$PATH" fi 
Enter fullscreen mode Exit fullscreen mode

Setting PATH the smart way

Part of the standard setup of packages like Ruby, Go and Node is to add a directory to your shell PATH variable so that executables can be found.

If I want to check the directory exists first, I could do this:

if [ -d '/usr/local/opt/ruby/bin' ]; export PATH="/usr/local/opt/ruby/bin:$PATH" fi 
Enter fullscreen mode Exit fullscreen mode

But I got tired of having that long syntax. So I made a function to do that, which I call like this:

prepend_path() { if [ -d "$1" ]; then export PATH="$1:$PATH" fi } 
Enter fullscreen mode Exit fullscreen mode

Usage:

# Ruby gems prepend_path /usr/local/opt/ruby/bin # Go packages. # Traditional path is '/usr/local/go/bin' or '/usr/bin'. # I created ~/.local to use that rather. prepend_path ~/.local/go/bin 
Enter fullscreen mode Exit fullscreen mode

Executing local packages

When working on Node projects, you normally have to run a script like this in the shell:

$ ./node_modules/.bin/eslint 
Enter fullscreen mode Exit fullscreen mode

I'd rather just run this:

$ eslint 
Enter fullscreen mode Exit fullscreen mode

To get that behavior, I decided to add ./node_modules/.bin to my PATH variable.

prepend_path_always() { export PATH="$1:$PATH" } prepend_path_always './node_modules/.bin' 
Enter fullscreen mode Exit fullscreen mode

Note that the values in PATH are read from left to right, so you must make sure your local packages are read before any global packages. In case you have say eslint installed locally and globally.

View the PATH

Here is what my PATH value looks like.

$ split_path /home/michael/.local/go/bin /home/michael/.deno/bin ./node_modules/.bin /home/michael/.local/bin ... 
Enter fullscreen mode Exit fullscreen mode

Note that the PATH value normally looks like this with colon separators, making it hard to read.

/home/michael/.local/go/bin:/home/michael/.deno/bin:... 
Enter fullscreen mode Exit fullscreen mode

So I created an alias called split_path which makes that more human-readable.

More about aliases in the next post in this series...

Top comments (7)

Collapse
 
rhamdeew profile image
Rail

Thank you, interesting post!

But I think it is better to run the binary from node_modules like this:

npx run eslint 
Enter fullscreen mode Exit fullscreen mode
Collapse
 
michaelcurrin profile image
Michael Currin

Thanks for the tip. Npx is nice for scaffolding create apps but I didn't know it works for local packages.

According to this post I can just do a command without run.

blog.scottlogic.com/2018/04/05/npx...

npx eslint 

Do you know if it respects the arguments?
Like if I wanted to run

eslint . # OR eslint --help 

Can I do that with npx? Like

npx eslint --help 
Collapse
 
rhamdeew profile image
Rail

Yes, you can)

Example:

run hexo version

npx hexo version 
➜ npx hexo version (node:90786) [DEP0061] DeprecationWarning: fs.SyncWriteStream is deprecated. hexo: 3.9.0 hexo-cli: 2.0.0 os: Darwin 19.5.0 darwin x64 http_parser: 2.8.0 node: 10.16.3 v8: 6.8.275.32-node.54 uv: 1.28.0 zlib: 1.2.11 brotli: 1.0.7 ares: 1.15.0 modules: 64 nghttp2: 1.39.2 napi: 4 openssl: 1.1.1c icu: 64.2 unicode: 12.1 cldr: 35.1 tz: 2019a 

run hexo version --debug

npx hexo version --debug 
➜ npx hexo version --debug 08:32:18.567 DEBUG Writing database to /Users/rail/Work/blogs/hmdwme_hexo/db.json 08:32:18.577 DEBUG Hexo version: 3.9.0 08:32:18.577 DEBUG Working directory: ~/Work/blogs/hmdwme_hexo/ 08:32:18.626 DEBUG Config loaded: ~/Work/blogs/hmdwme_hexo/_config.yml 08:32:18.638 DEBUG Plugin loaded: hexo-all-minifier 08:32:18.639 DEBUG Plugin loaded: hexo-generator-archive 08:32:18.640 DEBUG Plugin loaded: hexo-generator-category 08:32:18.643 DEBUG Plugin loaded: hexo-generator-feed 08:32:18.644 DEBUG Plugin loaded: hexo-generator-index 08:32:18.645 DEBUG Plugin loaded: hexo-generator-sitemap 08:32:18.646 DEBUG Plugin loaded: hexo-generator-tag 08:32:18.647 DEBUG Plugin loaded: hexo-renderer-ejs 08:32:18.651 DEBUG Plugin loaded: hexo-renderer-marked 08:32:18.719 DEBUG Plugin loaded: hexo-renderer-stylus 08:32:18.754 DEBUG Plugin loaded: hexo-server 08:32:18.826 DEBUG Plugin loaded: hexo-deployer-git (node:90673) [DEP0061] DeprecationWarning: fs.SyncWriteStream is deprecated. 08:32:18.839 DEBUG Script loaded: themes/hmdw/scripts/fancybox.js hexo: 3.9.0 hexo-cli: 2.0.0 os: Darwin 19.5.0 darwin x64 http_parser: 2.8.0 node: 10.16.3 v8: 6.8.275.32-node.54 uv: 1.28.0 zlib: 1.2.11 brotli: 1.0.7 ares: 1.15.0 modules: 64 nghttp2: 1.39.2 napi: 4 openssl: 1.1.1c icu: 64.2 unicode: 12.1 cldr: 35.1 tz: 2019a 08:32:18.842 DEBUG Database saved 
Thread Thread
 
michaelcurrin profile image
Michael Currin

Thanks

Collapse
 
michaelcurrin profile image
Michael Currin

Also my alias approach only works from the root. Does npx run from git root when run from anywhere?

Thread Thread
 
rhamdeew profile image
Rail • Edited

I tried different options to learn how it works.

package.json located in /srv/projects/awesome-project/frontend/web/

gulp located in /srv/projects/awesome-project/frontend/web/node_modules/gulp/bin/

Run npx gulp --tasks

1) on /srv/projects/awesome-project/frontend/web/

[08:38:32] Tasks for /srv/projects/awesome-project/frontend/web/gulpfile.js [08:38:32] ├── js [08:38:32] ├── css [08:38:32] └─┬ build [08:38:32] └─┬ <parallel> [08:38:32] ├── js [08:38:32] └── css 

2) on /srv/projects/awesome-project/frontend

Of course it doesn't work.

[08:38:36] Local gulp not found in /srv/projects/awesome-project/frontend [08:38:36] Try running: npm install gulp 

3) on /srv/projects/awesome-project/frontend/web/js

[08:38:49] Working directory changed to /srv/projects/awesome-project/frontend/web [08:38:52] Tasks for /srv/projects/awesome-project/frontend/web/gulpfile.js [08:38:52] ├── js [08:38:52] ├── css [08:38:52] └─┬ build [08:38:52] └─┬ <parallel> [08:38:52] ├── js [08:38:52] └── css 

4) on /srv/projects/awesome-project/frontend/web/js/dist

[08:39:07] Working directory changed to /srv/projects/awesome-project/frontend/web [08:39:10] Tasks for /srv/projects/awesome-project/frontend/web/gulpfile.js [08:39:10] ├── js [08:39:10] ├── css [08:39:10] └─┬ build [08:39:10] └─┬ <parallel> [08:39:10] ├── js [08:39:10] └── css 

Result - npx searches for the node_modules directory in the parent directories and tries to run the binary from there.

Thread Thread
 
michaelcurrin profile image
Michael Currin

Neat