What do you advice for shell usage?

  • Do you use bash? If not, which one do you use? zsh, fish? Why do you do it?
  • Do you write #!/bin/bash or #!/bin/sh? Do you write fish exclusive scripts?
  • Do you have two folders, one for proven commands and one for experimental?
  • Do you publish/ share those commands?
  • Do you sync the folder between your server and your workstation?
  • What should’ve people told you what to do/ use?
  • good practice?
  • general advice?
  • is it bad practice to create a handful of commands like podup and poddown that replace podman compose up -d and podman compose down or podlog as podman logs -f --tail 20 $1 or podenter for podman exec -it "$1" /bin/sh?

Background

I started bookmarking every somewhat useful website. Whenever I search for something for a second time, it’ll popup as the first search result. I often search for the same linux commands as well. When I moved to atomic Fedora, I had to search for rpm-ostree (POV: it was a horrible command for me, as a new user, to remember) or sudo ostree admin pin 0. Usually, I bookmark the website and can get back to it. One day, I started putting everything into a .bashrc file. Sooner rather than later I discovered that I could simply add ~/bin to my $PATH variable and put many useful scripts or commands into it.

For the most part I simply used bash. I knew that you could somehow extend it but I never did. Recently, I switched to fish because it has tab completion. It is awesome and I should’ve had completion years ago. This is a game changer for me.

I hated that bash would write the whole path and I was annoyed by it. I added PS1="$ " to my ~/.bashrc file. When I need to know the path, I simply type pwd. Recently, I found starship which has themes and adds another line just for the path. It colorizes the output and highlights whenever I’m in a toolbox/distrobox. It is awesome.

  • @[email protected]
    link
    fedilink
    51 year ago

    I primarily operate in strict standard compliance mode where I write against the shell specifications in the lastest Single Unix Specification and do not use a she-bang line since including one results in unspecified, implementation-defined behavior. Generally people seem to find this weird and annoying.

    Sometimes I embrace using bash as a scripting language, and use one of the env-based she-bangs. In that case, I go whole-hog on bashisns. While I use zsh as my interactive shell, even I’m not mad enough to try to use it for scripts that need to run in more than one context (like other personal accounts/machines, even).

    In ALL cases, use shellcheck and at least understand the diagnostics reported, even if you opt not to fix them. (I generally modify the script until I get a clean shellcheck run, but that can be quite involved… lists of files are pretty hard to deal with safely, actually.)

  • DasFaultier
    link
    fedilink
    English
    7
    edit-2
    1 year ago
    • I use bash, because I never had the time to learn anything else.
    • Like @[email protected] said, I use the #!/usr/bin/env bash shebang.
    • Nope
    • Also nope
    • Nope. Shell scripts reside in Git repos on Gitlab/Gitea/Forgejo and are checked out using Ansible playbooks onto the servers as necessary.
    • For scripts? Python. Read this blog post by the great @[email protected]. For interactive use? bash is just fine for me, though I’ve customized it using Starship and created some aliases to have colored/pretty output where possible.
    • Use shellcheck before running your scripts in production, err on the side of caution, set -o pipefail. There are best practices guides for Bash, use those and you’ll probably be fine.
    • Be prepared to shave yaks. Take breaks, touch grass, pet a dog. Use set -x inside your Bash script or bash -x scriptname on the CLI for debugging. Remember that you can always fallback to interactive CLI to test/prepare commands before you put them into your script. Think before you type. Test. Optimize only what needs optimization. Use long options for readability. And remember: Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows your address.
    • Nope, it’s absolutely not bad practice to create aliases to save you some typing in interactive shell. You shouldn’t use them inside your scripts though, because they might/will not be available in other environments.

    I switched to fish because it has tab completion Yeah, so does Bash, just install it.

    Oh, I also “curate” a list of Linux tools that I like, that are more modern alternatives to “traditional” Linux tools or that provide information I would otherwise not easily get. I’ll post i

    Tools

    Debian-Packages available

    • mtr
    • iputils-tracepath
    • iproute2
    • zsh
    • httpie
    • aria2
    • icdiff
    • progress
    • diffoscope
    • atop
    • powertop
    • ntopng
    • ethtool
    • nethogs
    • vnstat
    • ss
    • glances
    • discus
    • dstat
    • logwatch
    • swatch
    • multitail
    • lynis
    • ncdu (du-clone), alias du=“ncdu --color dark -rr -x --exclude .git --exclude node_modules”
    • nnn (fully-featured terminal file manager. It’s tiny, nearly 0-config and incredibly fast. https://github.com/jarun/nnn)
    • slurm
    • calcurse
    • newsbeuter
    • tig (“ncurses TUI for git. It’s great for reviewing and staging changes, viewing history and diffs.”)
    • qalc -ttyrec
    • taskwarrior
    • ttytter
    • ranger
    • ipcalc
    • pandoc
    • moreutils
    • googler
    • weechat
    • pdftk
    • abcde
    • dtrx
    • tload
    • ttyload
    • cockpit
    • sar
    • ht (hte Hex Editor)
    • dhex
    • ack (grep-clone)
    • silversearcher-ag (grep-clone)
    • ripgrep (“recursively searches file trees for content in files matching a regular expression. It’s extremely fast, and respects ignore files and binary files by default.”, https://github.com/BurntSushi/ripgrep)
    • exa (statt ls) https://the.exa.website/ (“replacement for ls with sensible defaults and added features like a tree view, git integration, and optional icons.”)
    • fzf (CLI fuzzy finder), alias preview=“fzf --preview ‘bat --color "always" {}’”
    • fd (simple, fast and user-friendly alternative to ‘find’, https://github.com/sharkdp/fd) -entr (watch-clone)
    • csvkit (awk-clone)
    • ccze (log coloring)
    • surfraw -hexyl (“hex viewer that uses Unicode characters and colour”, https://github.com/sharkdp/hexyl) -jq (“awk for JSON. It lets you transform and extract information from JSON documents”, https://stedolan.github.io/jq/) -pass (“password manager that uses GPG to store the passwords”, https://github.com/lunaryorn/mdcat)
    • restic (“backup tool that performs client side encryption, de-duplication and supports a variety of local and remote storage backends.”, https://restic.net/)
    • mdp (Markdown Presentation on CLI) -grepcidr
    • qrencode
    • caca-utils (show images on the CLI)
    • fbi ( & fbgs) (show images in Framebuffer device)
    • fbcat (take screnshot on framebuffer device)
    • nmap
    • micro (CLI Text Editor, ab Debian 11, https://micro-editor.github.io)
    • masscan (https://github.com/robertdavidgraham/masscan)
    • socat (Nachfolger von netcat, https://www.heise.de/select/ix/2017/11/1509815804306324)
    • dc3dd (patched version of GNU dd with added features for computer forensics)
    • smem (memory reporting tool)
    • free (Show Linux server memory usage)
    • mpstat (Monitor multiprocessor usage on Linux, part of sysstat package)
    • pmap (Montor process memory usage on Linux, part of the procps)
    • monit (Process supervision)
    • oping & noping
    • saidar (Curses-basiertes Programm für die Anzeige von Live-Systemstatistiken)
    • reptyr (Tool for moving running programs between ptys)
    • gron (https://github.com/tomnomnom/gron, makes JSON greppable, kann HTTP-Requests absetzen)
    • jc (https://github.com/kellyjonbrazil/jc, CLI tool and python library that converts the output of popular command-line tools and file-types to JSON or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.)
    • bat (cat-clone), alias cat=‘bat’ (“alternative to the common (mis)use of cat to print a file to the terminal. It supports syntax highlighting and - git integration.”, https://github.com/sharkdp/bat)
    • ioping (https://github.com/koct9i/ioping, simple disk I/0 latency measuring tool, auch für disk seek rate/iops/avg)
    • vd (Visidata, multipurpose terminal utility for exploring, cleaning, restructuring and analysing tabular data. Current supported sources are TSV, CSV, fixed-width text, JSON, SQLite, HTTP, HTML, .xls, and .xlsx)
    • pdfgrep
    • duf https://github.com/muesli/duf (combined df and du, ncurses-based)
    • nala (apt-alternate, https://gitlab.com/volian/nala, https://christitus.com/stop-using-apt/)
    • iprange
    • tldr
    • rmlint
    • nvtop (https://github.com/Syllo/nvtop, GPUs process monitoring for AMD, Intel and NVIDIA)
    • lf (lf (as in “list files”) is a terminal file manager written in Go with a heavy inspiration from ranger file manager)

    no Deb pkg avail

    ___

  • @[email protected]
    link
    fedilink
    41 year ago

    Yes, using bash on all boxen.

    Scripts start with #!/bin/sh ,because, that gives quicker execution times.

    Any simple aliases, I put in .bash_aliases

    Tried tcsh and zsh around 30yrs ago, all bash since then.

    • @[email protected]
      link
      fedilink
      21 year ago

      Do you have to chmod all your scripts when you include the shebang? Or do you have it configured to save with the right permissions?

  • wuphysics87
    link
    fedilink
    71 year ago

    Several things

    • write bash and nothing else (except posix sh)
    • find a good way to take notes. It shouldn’t be in your bashrc
    • only write fish for fish config
    • use $!/usr/bin/env bash
    • @[email protected]OP
      link
      fedilink
      English
      41 year ago

      Good idea I added a “iwish” command a while ago. Whenever I am pissed about gnome not being able to do something, or anything else that didn’t work as it should, I wrote “iwish gnome had only one extension app” and it would add a new line to my wishlist.md Maybe it would be good for notes too. inote bla

  • @[email protected]
    link
    fedilink
    English
    71 year ago

    That’s the way I do it:

    #!/usr/bin/env nix
    #! nix shell nixpkgs#nushell <optionally more dependencies>  --command nu
    
    <script content>
    

    But those scripts are only used by me

  • @[email protected]
    link
    fedilink
    31 year ago

    I use fish shell only now. Used to only write bash, but I’ve started writing some fish scripts. I wouldn’t try to plan too much WRT shell scripting up front. Just fix your pain points as you go.

  • @[email protected]
    link
    fedilink
    31 year ago

    Yes fish is great. It has some special syntax for functions, I will add my configs soo.

    set fish_greeting is useful to silence it.

    User scripts can go to ~/.local/bin which is already in the path.

    You can split up your shell configs into topics, and put them into ~/.config/fish/conf.d/abc.conf

  • exu
    link
    fedilink
    English
    6
    edit-2
    1 year ago

    I use Bash for scripts, though my interactive shell is Fish.

    Usually I use #!/usr/bin/env bash as shebang. This has the advantage of searching your PATH for Bash instead of hardcoding it.

    My folders are only differentiated by those in my PATH and those not.

    Most of my scripts can be found here. They are purely desktop use, no syncing to any servers. Most would be useless there.

    For good practice, I’d recommend using set -euo pipefail to make Bash slightly less insane and use shellcheck to check for issues.
    This is personal preference, but you could avoid Bashisms like [[ and stick to POSIX sh. (Use #!/usr/bin/env sh then.)

    With shortened commands the risk is that you might forget how the full command works. How reliant you want to be on those commands being present is up to you. I wouldn’t implement them as scripts though, just simple aliases instead.
    Scripts only make sense if you want to do something slightly more complex over multiple lines for readability.

    • @[email protected]OP
      link
      fedilink
      English
      31 year ago

      #/usr/bin/env bash typo? #!/usr/bin/env bash

      thx for the tips!

      I prefer single files over aliases since I can more easily manage each command.

  • @[email protected]
    link
    fedilink
    31 year ago

    Bash script for simple things (although Fish is my regular shell) and Node or Python scripts for complex things. Using #!/usr/bin/env node works just like it would for Bash so you know.

    • @[email protected]
      link
      fedilink
      English
      11 year ago

      This. I still write plenty of bash scripts, but I’ve noticed that except for really simple cases, I very quickly reach a point where I would have been better off using Python instead. And when I start with a Python scripts I often end up redoing it in Rust for a variety of reasons. It’s just easy to underestimate how serious a programming project is. At least I’ve never started something in bash that I needed to migrate to Rust.

      (I think a lot of people would see Go as the next logical step from Python, but I personally find some things about Go really irritating.)

  • Daniel Quinn
    link
    fedilink
    English
    3
    edit-2
    1 year ago

    I recommend writing everything in Bourne shell (/bin/sh) for a few reasons:

    • Bash is more capable, which is nice, but if you’re fiddling with complex data structures, you probably should be using a more maintainable language like Python.
    • Bash is in most places, but crucially not everywhere. Docker-based deployments for example often use Ash which is very similar to Bash, but lacks support for arrays and a few other things.
    • Bourne’s limitations force you to rethink your choices regularly. If you find yourself hacking around a lack of associative arrays for example, it’s probably time to switch to a proper language.

    Also two bits of advice.

    1. Use shellcheck. There’s a website that’ll check your script for you as well as a bunch of editor extensions that’ll do it in real time. You will absolutely write better, safer code with it.
    2. If your script exceeds 300 lines. Stop and rewrite it in a proper language. Your future self will thank you.
  • @[email protected]
    link
    fedilink
    121 year ago

    Do you use bash?

    Personally I use Bash for scripting. It strikes the balance of being available on almost any system, while also being a bit more featureful than POSIX. For interactive use I bounce between bash and zsh depending on which machine I’m on.

    Do you write #!/bin/bash or #!/bin/sh?

    I start my shell scripts with #! /usr/bin/env bash. This is the best way of ensuring that the same bash interpreter is called that the user expects (even if more than one is present or if it is in an unusual location)

    Do you have two folders, one for proven commands and one for experimental?

    By commands, do you mean bash scripts? If so, I put the ones I have made relatively bulletproof in ~/bin/, as bash usually makes them automatically on the path with this particular folder name. If I’m working on a script and I don’t think it’s ready for that, or if it goes with a specific project/workflow, I will move it there.

    Do you sync the folder between your server and your workstation?

    No. I work on lots of servers, so for me it’s far more important to know the vanilla commands and tools rather than expect my home-made stuff to follow me everywhere.

    good practice? general advice?

    Pick a bash style guide and follow it. If a line is longer than 80 characters, find a better way of writing that logic. If your script file is longer than 200 lines, switch to a proper programming language like Python. Unless a variable is meant to interact with something outside of your script, don’t name it an all caps name.

    is it bad practice to create a handful of commands like podup and poddown that replace podman compose up -d and podman compose down or podlog as podman logs -f --tail 20 $1 or podenter for podman exec -it "$1" /bin/sh?

    This is a job for bash aliases.

    • A Phlaming Phoenix
      link
      fedilink
      21 year ago

      Good advice. I’ll add that any time you have to parse command line arguments with any real complexity you should probably be using Python or something. I’ve seen bash scripts where 200+ lines are dedicated to just reading parameters. It’s too much effort and too error prone.

      • @[email protected]
        link
        fedilink
        41 year ago

        It depends. Parsing commands can be done in a very lightweight way if you follow the bash philosophy of positional/readline programming rather than object oriented programming. Basically, think of each line of input (including the command line) as a list data structure of space-separated values, since that’s the underlying philosophy of all POSIX shells.

        Bash is basically a text-oriented language rather than an object-oriented language. All data structures are actually strings. This is aligned with the UNIX philosophy of using textual byte streams as the standard interface between programs. You can do a surprising amount in pure bash once you appreciate and internalize this.

        My preferred approach for CLI flag parsing is to use a case-esac switch block inside a while loop where each flag is a case, and then within the block for each case, you use the shift builtin to consume the args like a queue. Again, it works well enough if you want a little bit of CLI in your script, but if it grows too large you should probably migrate to a general purpose language.

        • @[email protected]
          link
          fedilink
          4
          edit-2
          1 year ago

          Here’s a simple example of what I mean:

          #! /usr/bin/env bash
          
          while [[ -n $1 ]]; do
            case $1 in
              -a) echo "flag A is set" ;;
              -b|--bee) echo "flag B is set" ;;
              -c) shift; echo "flag C is $1" ;;
              --dee=*) echo "flag D is ${1#--dee=}" ;;
            esac
            shift
          done
          

          Showing how to do long flags with B and flags with parameters with C and D. The parameters will correctly work with quoted strings with spaces, so for example you could call this script with --dee="foo bar" and it will work as expected.

        • @[email protected]
          link
          fedilink
          11 year ago

          Hoho, now do that in POSIX shell.

          I had a rude awakening the day I tried it, but my scripts are bulletproof now (I think) so I don’t mind at this point

          • @[email protected]
            link
            fedilink
            11 year ago

            Imma be real, I never remember which parts of bash aren’t POSIX. Luckily it doesn’t matter in my line of work, but it’s good to be aware of if you have a job that often has you in machines running other types of UNIX.

  • @[email protected]
    link
    fedilink
    4
    edit-2
    1 year ago

    I use sh to attempt to keep it compatible with POSIX systems.

    I use pain bash. Never really tried zsh and fish, since most of my Linux work is on servers and I don’t really care for extra features.

    I try and write idempotent scripts when possible.

    I wouldn’t create those aliases on a fleet because writing them to the configuration file of your shell in an idempotent fashion is hacky and my VMs are like cattle.