A Linux script management CLI written in Rust

Overview

pier ~ A Linux script management tool

Build Status crates.io

A central repository to manage all your one-liners, scripts, tools, and CLIs. Add, remove, list, and run scripts - storing metadata to easily find them later. No more digging through your bin folder...

Boat pier

Description

If you've spent any amount of time in the terminal you no doubt have built up a lovely collection of one-liners, scripts, useful tools, and CLIs. Whenever you want to use them you dig through your bin folder trying to remember what you called the script... Linux users love hard-to-remember naming conventions.

Scripts should be first-class citizens. In a GUI world we can find our programs using a menu of sorts. In the terminal scripts get lost.

The idea behind pier is to create a central repository for all your scripts, and provide a way to attach metadata about these scripts. Using pier you can add, remove, list, and run scripts. These can be managed by pier in a human-readable TOML config, or you can use it to catalog existing scripts that you may have lying around - you'd then simply add the metadata for the specific script, and attach it to the name in the PATH.

Installation

From Crates.io: cargo install pier

From GitHub release: simply download the release binary

Using Nix package manager:

  1. From GitHub release: make install or nix-env -if derivation.nix
  2. From source: update src in derivation to ./.

Recent Breaking Changes

Version 0.1.4:

The configuration variable default_interpreter has been removed:

default_interpreter = ["foorunner", "-c"]

So when upgrading from to 0.1.4 from an earlier version you will need to instead specify the variable in this format:

[default]
interpreter = ["foorunner", "-c"]

Operation

Use pier --help to display help on commandline or see src/cli.rs for a more detailed spec.

pier 0.1.4
Benjamin Scholtz, Isak Johansson
A simple script management CLI

USAGE:
    pier [FLAGS] [OPTIONS] <alias>
    pier [FLAGS] [OPTIONS] <SUBCOMMAND>

FLAGS:
    -h, --help       
            Prints help information

    -V, --version    
            Prints version information

    -v, --verbose    
            The level of verbosity


OPTIONS:
    -c, --config-file <path>    
            Sets a custom config file.
            
            DEFAULT PATH is otherwise determined in this order:
            
            - $PIER_CONFIG_PATH (environment variable if set)
            
            - pier.toml (in the current directory)
            
            - $XDG_CONFIG_HOME/pier/config.toml
            
            - $XDG_CONFIG_HOME/pier/config
            
            - $XDG_CONFIG_HOME/pier.toml
            
            - $HOME/.pier.toml
            
            - $HOME/.pier
            
             [env: PIER_CONFIG_PATH=]

ARGS:
    <alias>    
            The alias or name for the script.


SUBCOMMANDS:
    add       Add a new script to config.
    edit      Edit a script matching alias.
    help      Prints this message or the help of the given subcommand(s)
    list      alias: ls - List scripts
    remove    alias: rm - Remove a script matching alias.
    run       Run a script matching alias.
    show      Show a script matching alias.
  • pier list
  • pier add "ip link set wlp58s0 down && sleep 5 && ip link set wlp58s0 up" --alias refresh-wifi
  • pier refresh-wifi

Example pier TOML config

[scripts.refresh-wifi]
alias = "refresh-wifi"
command = "ip link set wlp58s0 down && sleep 5 && ip link set wlp58s0 up"

[scripts.twa-analyze]
alias = "twa-analyze"
command = "docker run --rm -t trailofbits/twa -vw"
tags = [ "infosec" ]

[scripts.enabled-services]
alias = "enabled-services"
command = "systemctl list-unit-files --state=enabled"

[scripts.flush-docker]
alias = "flush-docker"
command = "docker container stop $(docker container ls -a -q) && docker system prune -a -f --volumes"
description = "A script to clear out old Docker containers and images"
tags = [ "docker", "flush" ]

Example pier list output

▶ pier list           
 Alias             | Command 
-------------------+----------------------------------------------------------------------------------------------------------------
 fromscratch       | appimage-run ~/AppImage/FromScratch.1.4.3.AppImage 
 nspawn-bionic     | sudo systemd-nspawn --bind=/tmp/.X11-unix -D /var/lib/machines/bionic --bind /home/bscholtz:/home/bscholtz 
 bspwm-refresh     | .config/bspwm/bspwmrc 
 flush-docker      | docker container stop $(docker container ls -a -q) && docker system prune -a -f --volumes 
 zfs-compression   | sudo zfs get all | grep compressratio 
 mongo-docker      | docker run --name mongodb -d mongo:latest 
 forward-mongo     | kubectl port-forward mongo-molecule-set-0 27018:27017 
 refresh-wifi      | ip link set wlp58s0 down && sleep 5 && ip link set wlp58s0 up 
 lepton            | appimage-run ~/AppImage/Lepton-1.8.0-x86_64.AppImage 
 ledger            | appimage-run AppImage/ledger-live-desktop-1.6.0-linux-x86_64.AppImage 
 reload-urxvt      | xrdb ~/.Xresources 
 kill-docker       | rm -rf /var/lib/docker 
 reload-xresources | xrdb ~/.Xresources 
 graphiql          | appimage-run ~/AppImage/graphiql-app-0.7.2-x86_64.AppImage 
 enabled-services  | systemctl list-unit-files --state=enabled 
 ports             | netstat -tulpn 
 chmod-copy        | chmod --reference= 
 zfs-drop-caches   | sync; echo 2 | sudo tee /proc/sys/vm/drop_caches 
 update            | sudo nix-channel --update && sudo nixos-rebuild switch 
 flush-untagged    | docker images -q --filter dangling=true | xargs -r docker rmi 
 twa-analyze       | docker run --rm -t trailofbits/twa -vw 
 parity-ubuntu     | docker image pull yodascholtz/parity-ubuntu:latest && docker run -p 8545:8545 yodascholtz/parity-ubuntu:latest

Execute pier scripts in any interpreted languages

Scripts starting with a shebang #! will be run with the specified interpeter just like it would in a normal script. Pier does this by creating a temp file from your script, executing it and then finally cleaning the file up. This allows you to write your pier script in python, node.js etc. even compiled languages can be run if using something like scriptisto.

Shebang example config

[scripts.run_rust_script]
alias = "run_rust_script"
command = '''
#!/usr/bin/env scriptisto

// scriptisto-begin
// script_src: src/main.rs
// build_cmd: cargo build --release && strip ./target/release/script
// target_bin: ./target/release/script
// files:
//  - path: Cargo.toml
//    content: |
//     package = { name = "script", version = "0.1.0", edition = "2018"}
//     [dependencies]
// scriptisto-end


fn main() {
    println!("This is a rust script!");
}

'''

[scripts.run_python]
alias = "run_python"
command = '''
#!/usr/bin/env python3
import sys

print("Running python with version {}".format(sys.version))

'''

Setting the default shell / interpreter

By default if no shebang is specified pier will try to use your default shell to execute the script inline. This can be overwritten with the variable interpreter. It needs to be a list with the first item being the binary and the rest is any flags necessary.

Default interpreter example config

# Sets the default interpreter, the first item in the list should be the binary and the rest are the arguments for the interpreter cli option.
[default]
interpreter = ["node", "-e"]

# Runs as the fallback interpreter nodejs as it's lacking a shebang
[scripts.hello_world_nodejs]
alias = "hello_world_nodejs"
command = '''
console.log("Hello world!")

'''

# This will be run as a posix sh script as it has a shebang
[scripts.a_shell_script]
alias = "a_shell_script"
command = '''
#!/bin/sh

nohup st > /dev/null 2>&1&

'''

Origin

Originally intended as a way to manage Docker one-liners, the name pier continues along the same maritime theme. I realized Pier can manage a lot more than just Docker scripts.

Roadmap to v1.0.0

  • Fuzzy search + autocomplete e.g. prompts for alias
  • Complete base features: mv, tag
  • Rework testing
  • Update documentation e.g. contributor guidelines, templates
Comments
  • Config file generation

    Config file generation

    Hi, just getting started with the tool, so I may have overlooked something!

    From what I understand, we are meant to create our own config file and store the path as an environment variable for pier, right?

    Would it be beneficial to have pier automatically generate a config file (and store it in /usr/bin or something) by default? Or is this against the vision/idea in some way?

    opened by niniack 11
  • Weird parsing of escaped characters

    Weird parsing of escaped characters

    Hi, I'm trying to add a one-liner with this snippet in it: sed -r "s/^[0-9.]+\s+//" However, when it gets parsed, this part of the command transforms to: sed -r s/^[0-9.]+s+//

    Once I replaced \s with [ ], the command parsed correctly. Is this a bug or something I have to work around?

    opened by rirze 11
  • # Ideas / thoughts about how to implement args.

    # Ideas / thoughts about how to implement args.

    The args feature has been mocked up for a while and I've had it in the back of my mind how it would be good to implement it, initially I was thinking you could just do some templating but I pretty soon realized that it's a pretty big security flaw as you could then literally inject code before you run it.

    Right now I'm leaning towards the best option would be to implement arguments/options as env variables, perhaps via a key/value cli arg with the ability to set defaults for a tag/script in the configt.

    I imagine the cli option for setting environment variables to something like -E/--env it could look something like this perhaps: pier run build_something -E RUST_BACKTRACE:1 -E DB_HOST:127.0.0.1

    opened by Plommonsorbet 8
  • Code cleanup

    Code cleanup

    Hey!

    Thought I would do some more code cleanup and reorganizing, also updated the help text and some other small things like adding aliases to the subcommands, like ls for list and rm for remove.

    I also changed from clap to structopt as it makes the commandline options a lot more structured.

    /Isak

    opened by Plommonsorbet 7
  • Improve table & colorize

    Improve table & colorize

    Hey,

    Love your work, but I felt the table needed some more life. So I custom-made a table, with space for titles and descriptions, and put some color on it. It also works with pipes. I also created a result specific type, analog to PierError. Looking forward to hear your comments.

    Cheers

    opened by DanielRivasMD 4
  • Show output to stderr as it happens.

    Show output to stderr as it happens.

    I'm using a shell script managed by pier to perform various update tasks. One of these tasks is running rustup update. Currently, when I run this script, some of the progress output goes to stderr and is only visible after the whole script finishes. I think it would be better to show stderr output as it is produced by the script subprocess.

    I think the issue might stem from this line.

    opened by korrat 4
  • Open in $EDITOR feature.

    Open in $EDITOR feature.

    If no script arg is entered at command line it will try and open the users EDITOR. Also added subcommand edit for editing an already defined command, only supports editing the script. Would be nice to add the ability to edit the tags, description etc as well.

    opened by Plommonsorbet 4
  • Multiline command not displaying table correctly when running list

    Multiline command not displaying table correctly when running list

    The list command is creating a new table row when dispaying multiline commands, ex:

    Alias | tags | Command --- | --- | --- 1-test-single-line | - | echo this is a single line command 2-test-multi-line | - | echo This - | - | echo is - | - | echo over - | - | echo multiple - | - | echo lines 3-test-another-single-line | - | echo this is another single line command

    Converted the ascii table to markdown table for nicer viewing. The minus sign can be interpreted as nothing or whitespace.

    Config to reproduce error:

    [scripts.1-test-single-line]
    alias = '1-test-single-line'
    command = '''
    echo this is a single line command
    '''
    
    [scripts.2-test-multi-line]
    alias = '2-test-multi-line'
    command = '''
    echo This
    echo is
    echo over
    echo multiple
    echo lines
    '''
    
    [scripts.3-test-another-single-line]
    alias = '3-test-another-multi-line'
    command = '''
    echo this is another single line command
    '''
    
    opened by Plommonsorbet 4
  • implement and test copy subcmd

    implement and test copy subcmd

    The new subcmd takes two alias, copys over the script to the new alias. It checks the existing alias exist and the new script doesn't. Added test to verify copy. Fixes #45

    Note: Hey guys. New to rust here but interested in the tech. Comments and reviews welcomed :)

    opened by yhung119 3
  • implement argument passing

    implement argument passing

    If pier supports passing arguments to the scripts, it would be flexible. So I have tried to implement.

    I wanted to split alias and arguments which are combined into a Vec<String> in Cli structure, but when I tried, the binary always crashed. I would happy if someone implements that :).

    opened by jayong93 3
  • Run output boiler plate suggestions?

    Run output boiler plate suggestions?

    Currently it's a bit hard to pipe the output of pier into anything else as there is a bit of boiler plate in the run output. I've been thinking a bit about how to solve this, some of my ideas are:

    • Remove it completely.
    • Move it to only print on verbose mode.
    • Add an option for a 'quiet-mode'

    Personally I think the best option would be to move it to only print in verbose mode, I think it can be nice to see sometimes. But usually you want to be able to do something with the output and having to use a flag every time you want to pipe pier to something else could get a bit annoying.

    I'd love to hear your opinion Ben / anyone else :)

    opened by Plommonsorbet 3
  • Bump prettytable-rs from 0.8.0 to 0.10.0

    Bump prettytable-rs from 0.8.0 to 0.10.0

    Bumps prettytable-rs from 0.8.0 to 0.10.0.

    Release notes

    Sourced from prettytable-rs's releases.

    v0.10.0

    Fixed

    • Fix panic due to incorrect ANSI escape handling #137
    • Fix display of empty tables #127

    Changed

    • Remove the unsafe code in Table::as_ref #146
    • Switch atty to is-terminal #151
    • Minimal Supported Rust Version bumped to 1.56

    Thanks

    v0.9.0

    This release has been updated with latest dependencies versions.

    This crate has been abandonned without notice for quite a while due to some personnal reasons. My apologies for that. I'll try to do my best to continue to maintain it, at least for security updates. If I can't the find time to do it, I'll have no other option than deprecating it, or find new contributors to handover the maintenance to. Feel free to raise your hand if you're interrested. In the meantime, please expect a low update rate, and again please accept my apologies.

    I'll do a pass on opened PRs after summer vacations.

    Changelog

    Sourced from prettytable-rs's changelog.

    0.10.0 (2022-12-27)

    Fixed

    • Fix panic due to incorrect ANSI escape handling (#137)
    • Fix display of empty tables (#127)

    Changed

    • Remove the unsafe code in Table::as_ref (#146)
    • Switch atty to is-terminal (#151)
    • Minimal Supported Rust Version bumped to 1.56

    Thanks

    #127: phsym/prettytable-rs#127 #137: phsym/prettytable-rs#137 #145: phsym/prettytable-rs#145 #146: phsym/prettytable-rs#146 #151: phsym/prettytable-rs#151

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • :feature-request: add fuzzy search menu bolow

    :feature-request: add fuzzy search menu bolow

    may its a bit different concept. i possible please add to your to-do-list: add fuzzy search menu bolow. i tried to do something with https://github.com/sl5net/Lintalist4Linux thanks

    opened by sl5net 2
  • Add Shell basic shell completion.

    Add Shell basic shell completion.

    I had to change some of the cli options around to make the shell completions more usable. To the user the cli should act the same however.

    Added build script for generating completion files to SHELL_COMPLETIONS_DIR or completions.

    TODO installation script for completion files.


    opened by Plommonsorbet 0
  • Allow new scripts to be added from stdin with the add command

    Allow new scripts to be added from stdin with the add command

    This option would make migrating existing shell scripts to pier a lot easier!

    Example usage

    echo 'for i in {1..10}; do echo $i; done' | pier add -a count_to_ten

    Perhaps in the future we could add a json input option as well where you dump the whole script struct into stdin. :)

    enhancement 
    opened by Plommonsorbet 0
  • Shell completion

    Shell completion

    Pier is lacking shell completions at the moment for all the cli options, however since pier is using clap / structopt this does not seem relatively easy to do.

    To start with perhaps we should limit it to bash / zsh just to keep it simple, however it seems like it's possible to generate powershell / fish completions via clap as well.

    I'm not sure how well pier works on windows right now at least, but I'd be curious to know.

    Useful links:

    docs.rs about the shell generation in clap structopt example code for generating shell completions

    enhancement 
    opened by Plommonsorbet 4
  • Maybe we should create a gihub wiki or a pier-contrib repo?

    Maybe we should create a gihub wiki or a pier-contrib repo?

    I think it would be cool if we had some sort of platform where we can share scripts, workflow examples, extensions etc. I always appreciate learning about other people's workflows and it feels appropriate to have something like that considering the tool. It's also a good place to increase the documentation and link to related tools.

    • Here's a very simple fzf menu i made that perhaps would be interesting to add to something like that:
    pfz() {
        pier list -q \
            | fzf -m --preview 'pier show {} | bat --color=always' \
            --bind 'ctrl-y:execute(pier show {} | xsel -b)+abort' \
            | xargs -n 1 -I {} pier run {}
    }
    
    • I was considering creating an emacs plugin for pier as way to learn elisp, my idea is implementing a plugin with fuzzy selection, execution, repl / paste to buffer etc. Obviously that would go in a separate repository but things like that would be a good place to link from a wiki.

    Some examples of what I mean:

    • https://github.com/junegunn/fzf/wiki/examples
    • https://github.com/eth-p/bat-extras
    • https://github.com/vivien/i3blocks-contrib
    opened by Plommonsorbet 5
Releases(v0.1.4)
Owner
Pier
Organisation for Pier CLI and contrib repos.
Pier
This is a `Rust` based package to help with the management of complex medicine (pill) management cycles.

reepicheep This is a Rust based package to help with the management of complex medicine (pill) management cycles. reepicheep notifies a person(s) via

Daniel B 24 Dec 13, 2023
Write a simple CLI script, that when given a 64-byte encoded string

Write a simple CLI script, that when given a 64-byte encoded string, it finds a suitable 4-byte prefix so that, a SHA256 hash of the prefix combined with the original string of bytes, has two last bytes as 0xca, 0xfe. Script should expect the original content of the string to be passed in hexadecimal format and should return two lines, first being the SHA256 string found and second 4-byte prefix used (in hexadecimal format).

Andy Bell 0 Feb 4, 2022
Auto Fan Management Utility in Linux Systems for Monster Laptops

Auto Fan Management Utility in Linux Systems for Monster Laptops Monster Laptoplar için Linux Sistemlerde Oto Fan Yönetimi TR Monster laptoplar gömülü

null 2 Aug 22, 2022
comfy is a flexible command script manager / runner written in Rust

comfy is a cross-platform command script manager / runner tool, which allows you to run commands in the command line itself, but being these predefined in a portable and universal .comfy file.

daCoUSB 17 Nov 12, 2021
A script language like Python or Lua written in Rust, with exactly the same syntax as Go's.

A script language like Python or Lua written in Rust, with exactly the same syntax as Go's.

null 1.4k Jan 1, 2023
⚡️ NFT Snapshot script written in Rust for blazingly fast speeds ⚡️

⚡️ NFT SNAPSHOT ⚡️ This project uses rust's blazingly fast performance along with the ethers-rs library to read blockchain state. Setup You will have

Trevor Johnson 4 Oct 14, 2022
A little command-line script written in Rust to interface with Discord webhooks.

Rust Discord Webhook Agent This is a little "script" I wrote for practice with Rust and asynchronous operations within Rust. Getting started Clone thi

David Chen 2 Sep 7, 2022
Text-based to-do management CLI & language server

☑️ Todome (日本語版はこちら) Todome is a notation developed for making and editing to-do lists. It is inspired by Todo.txt, and in fact some of the todome not

monaqa 16 Aug 17, 2022
CLI for ERC-5564 compliant stealth address management on evm chains

stealthereum-cli This is a bare bones CLI written in rust for ERC-5564 compliant stealth address management on evm chains It's currently the easiest w

κασσάνδρα.eth 6 Oct 11, 2023
TMM is a Linux native game modding tool. it allows to install and depoly mods for Linux native and wine games.

Tux Mod Manager TMM is a Linux native mod manager made with the Tauri toolkit. It can install, load, remove and deploy mods for both Linux native and

Mathiew May 119 Dec 27, 2022
A Rust-based shell script to create a folder structure to use for a single class every semester. Mostly an excuse to use Rust.

A Rust Course Folder Shell Script PROJECT IN PROGRESS (Spring 2022) When completed, script will create a folder structure of the following schema: [ro

Sebastián Romero Cruz 1 Apr 10, 2022
Simple node and rust script to achieve an easy to use bridge between rust and node.js

Node-Rust Bridge Simple rust and node.js script to achieve a bridge between them. Only 1 bridge can be initialized per rust program. But node.js can h

Pure 5 Apr 30, 2023
A rust script to convert a better bibtex json file from Zotero into nice organised notes in Obsidian

Zotero to Obsidian script This is a script that takes a better bibtex JSON file exported by Zotero and generates an organised collection of reference

Sashin Exists 3 Oct 9, 2022
Replace an app's icon from a png with a single terminal script. Made with Rust

Replace macOS App Icon Replace an app's icon from a png with a single terminal CLI. Made with Rust

Kunal Bagaria 8 Aug 3, 2022
Diplo is a script runner and dependency manager made in rust mainly for Deno.

Diplo is a script runner and dependency manager made in rust mainly for Deno. Documentation Tricked.pro/diplo Installing - windows installer Features

Tricked 23 May 9, 2022
A simple script (in Rust lang) to create HTML from SVD

A simple script to create HTML from an SVD file This is a simple script written in Rust language to create a single HTML file from an SVD file. It's r

Björn Quentin 14 Aug 22, 2022
Fortipwn - Forti CVE-2022-40684 enumeration script built in Rust

fortipwn Forti CVE-2022-40684 enumeration script built in Rust. Uploads an SSH public key into authorized_keys, allowing an attacker to SSH into a ser

null 3 Oct 24, 2022
Fix the simple rust script as shown in README.md

Rust Fix Me Steps Create a Github account. (If you already have one no issues) Star this repository. Fork this repository to your Github account. Clon

Ganesh Chandrasekaran 48 Dec 9, 2022
A small script in rust to get the cpu usage in %'s with a gradient color for the text

cpu_usage-polybar A small script in rust to get the cpu usage in %'s with a gradient color for the text To get it to work on your PC you will have to

Sara 4 Apr 18, 2023