Show HN: Oh-heck, a terminal command for when you forget other terminal commands
oh-heck.dev
oh-heck.dev
I'm sure these are just oversights but it leaves a very bad taste in my mouth!
oh-heck "Bring up the network interface. Goddamit Linux where did ifconfig go? Why do you have to NIH everything?" echo "Local IPs: "
ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}'
systemd-resolve --status | grep -A 2 Servers | sed 's/\ //g'
ip route show
curl --silent ipinfo.io | grep -E '\"ip|hostname|city' | sed 's/\"//g'
Hope this helpsI know I can create aliases and whatnot, but I'm a consultant, when I was still hands on with the tools I'd log into 30+ different customer's environments every year. Many were isolated from the Internet and whilst I did carry my dotfiles around on a USB (Along with some binaries of useful tools that are so often lacking on enterprise systems) I couldn't always use them.
When you run a command it moves the cursor (point in Emacs) to the beginning of the line and shows output below it. If you start typing it jumps to a new prompt allowing you to enter a separate command. If instead you move right from the beginning of the line it sees you are correcting/tweaking the command and doesn't jump to a new line when you type something. If you press space it acts like a pager.
It's pretty neat because it allows you to review the output without getting in the way.
The results are nicely formatted and color-coded. Give it a try in your terminal:
curl https://cheat.sh/rsync
I've found it to be really handy for things like awk, rsync, ssh, and others with byzantine parameters. Not to mention it's free.> Well, first, calm yourself, you fool. Once you've regained your composure, just type `oh-heck` into Terminal and follow the steps you numbskull.
I think that they're trying to be clever, but I prefer to not be insulted by my tools.
$ sudo whoami
[sudo] password for user:
Your mother was a hamster and your father smelt of elderberries!
[sudo] password for user:
Your mind just hasn't been the same since the electro-shock, has it?
[sudo] password for user:
sudo: 3 incorrect password attemptsReminds me of the days installing sl on FreeBSD servers. Someone typos the most common and basic of commands and they watch a steam locomotive journey across their screen. It even has different versions based on common ls switches.
And I just found it's still available. https://www.cyberciti.biz/tips/displays-animations-when-acci...
Might be worth giving the website/messaging a once-over
Looks neat! I've already been using github copilot which I've found brings some more joy into coding (even when it's a little off).
Is the input to oh-heck the complete GPT-3 prompt. Or is there something else added to it before sending to GPT-3?
Is there any specific training used for this task? Or just off the shelf GPT-3?
I'm assuming that this tool is for people who aren't familiar with the system enough to get what they need from the man pages and would rather not invest the time to become deeper on it.
If you don't remember the command you need to use, how can you be sure it is the correct command and options before you run it?
edit: typo
On the other hand if you are doing something dangerous or risky or you don't understand the suggested command, maybe you shouldn't use this tool without searching more info first.
That sounds suspciously like smitty[0].
Which was a useful tool when I was learning AIX. I'd expect a similar tool could be useful for learning other systems too.
Only a fool would rely solely a tool like this to run things you don't understand.
That doesn't make it a dangerous tool to use though.
It asks you for confirmation before running it.
sudo rm -rf /Example:
# 2022-02-07
# because `poetry show --outdated` includes *all* packages (!), not just top-level dependencies
function poetry-show-outdated {
poetry show --outdated | grep --file=<(poetry show --tree | grep '^\w' | cut -d' ' -f1)
}
Or: function disk-usage-summary () {
# output high-level disk usage stats
set -x
du --human-readable --summarize
du --human-readable --max-depth=1
df --human-readable --total
set +x
}If I don't necessarily want to run all of the commands, I make a "do-nothing script" [1][2] that just echoes them out instead.
I don't have a generalized example of undo / redo in bash commands, since I don't believe it's possible, but for example, if I'm running a destructive command, I prefer to run the dry run version first, then have a confirmation prompt [3] before running the destructive action.
[1]: https://news.ycombinator.com/item?id=20495739
Microsoft announced on September 22, 2020, that it had licensed "exclusive" use of GPT-3; others can still use the public API to receive output, but only Microsoft has access to GPT-3's underlying model. https://en.wikipedia.org/wiki/GPT-3
Does it handle questions that would result in piping commands together like “how do I get the third element in a JSON response from a curl command?”
This will be a great command alongside “fuck”
Oh, heck, go fuck yourself with a sharp cactus!
Led to finding this funny snippet in the 1992 ev_keymap.h file:
#define NX_NUMKEYCODES 256 /* Highest key code is 0xff. ADB used to use 0x80 for keydown state, but who the heck uses adb anymore. */
Boy was I wrong.
Using a specialized language for interacting with a computer is because NLP is so very hard.
oh-heck "is there a bash script I can use to hack the NSA?"Most frequently, it looks up the first stackoverflow answer and prints it.
TLDR community managed man pages https://tldr.sh/
Cheat Sheet access to community driven docs http://cht.sh/
Bro pages (like TLDR, but without the great name) http://bropages.org/
I'm the kind of person that prefers wrapping commands with terrible UI in functions with much better UI though https://github.com/pmarreck/pac . Like who the fuck thought that "pacman -Syyu" (where the number of y's semantically changes the meaning) would be a great idea? An idiot, a sadist or an autist, that's who. Certainly not someone who actually cares about normal humans.
In my opinion, instead of writing all these helper or cheatsheet functions as constant reminders of how bad the TUI (text user interface) is on these commands, someone should release a library of wrappers that wraps all of these turds (I'm sorry, "diamonds in the rough") in sensible and consistent TUI with consistent option formats, autocompletes, maybe some inline documentation while you type the command, etc. And then we wouldn't need all these band-aid tools.
I can say as an Arch fan but pacman command-tool despiser (did I mention that it doesn't at all try to stop you from easily breaking your dependency structure JUST in order to support some very corner use-cases?), prior to writing pac I was "man pacman"'ing for months, and after I finished it I haven't needed to do that EVER. (Yet.)
The "ip" command is an example of one I'd say has a good TUI.
$ apropos network
interfaces (5) - network interface configuration for ifup and ifdown
aseqnet (1) - ALSA sequencer connectors over network
byteorder (3) - convert values between host and network byte order
ctstat (8) - unified linux network statisticscreate_automation_image_overlay(8), -(8) - ."====================== create_automation_image_overlay overlay automation image content onto another directory ." ."
and
CPANPLUS::Internals::Source::Memory(3pm) - In memory implementation n .SS "$cb->_|_memory_retrieve_source(name => $name, [path => $path, uptodate => BOOL, verbose => BOOL])" .SS "$cb->_|_memory_retrieve_source(name => $name, [path => $path, uptodate => BOOL, verbose => BOOL])" Subsection "$cb->__memory_retrieve_source(name => $name, [path => $path, uptodate => BOOL, verbose => BOOL])" This method retrieves a storabled tree identified by $name. It takes the following arguments: name" 4 Item "name" The internal name for the source file to retrieve. uptodate" 4 Item "uptodate" A flag indicating whether the file-cache is up-to-date or not. path" 4 Item "path" The absolute path to the directory holding the source files. verbose" 4 Item "verbose" A boolean flag indicating whether or not to be verbose. Will get information from the config file by default. Returns a tree on success, false on failure. n .SS "$cb->_|_memory_save_source([verbose => BOOL, path => $path])" .SS "$cb->_|_memory_save_source([verbose => BOOL, path => $path])" Subsection "$cb->__memory_save_source([verbose => BOOL, path => $path])" This method saves all the parsed trees in storabled format if Storable is available. It takes the following arguments: path" 4 Item "path" The absolute path to the directory holding the source files. verbose" 4 Item "verbose" A boolean flag indicating whether or not to be verbose. Will get information from the config file by default. Returns true on success, false on failure
apropos directory | grep -i list
And now it's just 7 options, where `ls` is easy to find :)edit: I forget how apropos is named.
alias halp=aproposBut it turns out apropos is just a regular word. Once I learned this, I haven't had any more trouble with it.
apropos : Of an appropriate or pertinent nature.
[0] https://en.wiktionary.org/wiki/apropos [1] https://www.mankier.com/1/apropos.mandoc#History
(Also, `man --apropros` is the long option fwiw. I'm not really suggesting that as a better alternative though!)
Simply, like many, I have bash set up to record commands in .bash_history. I have it flush all the time, so .bash_history is always current.
# keep persistent bash history across sessions
export PROMPT_COMMAND='history -a;history -n'
export HISTCONTROL=ignoredups
shopt -s histappend
Next, I have a simple cron job running every minute. file=/tmp/work.$$
cat ~/.bash_history ~/.unique_bash | grep -v findcmd | sort -u > $file
mv $file ~/.unique_bash
Then, I have a script called "findcmd" that simply greps my .unique_bash file. for var in "$@"
do
cmd="| grep \"$var\" $cmd"
done
cmd="cat ~/.unique_bash $cmd"
eval $cmd
In the end, when I need to figure something out, I head to the internet. Those commands are then captured for posterity in the .unique_bash file. If I want to know how to post a JSON file to an endpoint using Curl, then $ findcmd curl json
And all those curl commands show up.It won't let me do something I don't know, but it make my memory much, much longer.
And, yea, I admit there have been instances where I've completely forgotten the command, and had to head back to the web. But when I've done that, I can hit my history and see how I used it.
If, sometimes, a "bad command", a command done wrong, too many of the same thing, just lingers, I can go edit it out. But most of the time I don't bother.
Link: https://github.com/junegunn/fzf
In particular, shell key bindings for fzf: https://github.com/junegunn/fzf#key-bindings-for-command-lin...
Most importantly I have an alias set up for the letter h , that greps, case insensitive .bash_history. ( grep -i $1 .bash_history ).
So typing in the cli: # h awk gives me all my awk commands.
And second , as a global history search across all my VMs/instances, (as I already make extensive use of splunk and splunks universal forwarder log forwarding app/tool) , all vms have their splunk universal forwarder service set to send any updates to .Bash_history to my central spunk server. thus I’m able to globally search the bash history from any VM globally, going back forever (I search that via the splunk web gui i mean). All works great!
I think I should just put a symlink called explorer.exe in my ~/bin/ and then I know where to look ;)
Because a man page for how to remove a limit of 50 files in a certain directory created after a certain date is equal to an AI-powered script to make the entire almost unreadable command in 2 seconds.
nobody knows enough from reading manuals for UN*X because it is too hard. everyone I talk to who says they have done it are still missing fundamental info, like for instance any one i talk to will probably not undersand that sudo is insecure for 99% of use cases and start crying when i explain to them that you can just use ptrace to capture the password or replace some bash envars to hijack the command. nobody knows how to declare a variable in a signal handler (see signal handling for fun and profit), because there is no comprehensive overview of C called "stuff you should know before actually programming in this".
the problem with trying to learn a UN*X system from within is that everything is scattered everywhere, and there is no comprehensive overview of any part of the system (they try to make some, but they are always missing something important, or dont mention how this would work in the context of a practical system where other subsystems change the behavior and requirements of this one), and the parts which take too long for anyone with a life to learn are always changing, like in linux ip tools, iptables/whatever alternative, and PAM, init (init is hard because you have to learn about how to manage environment and session properly which involves some tens of pages of man pages enumerating subtle details) systemd, pulseaudio. every tool has its own DSL for the trivial task of accepting parameters and parsing configs. to use apropos you first have to setup some database thing (yeah i dont remember).
learning C libs from the man pages is a perfect example. to do trivial stuff requires some hours of reading every day, and when you come back to use those functions again you will not remember most of them and have to look them up again, and they are:
- full of irrelevant info, the "BUGS" section, the "examples" section, conformance issues (which are not something you have in other languages' libraries),
- unneeded "this and that is UB" followed 5 minutes later by realizing 5 other things they did not write about is UB followed by philisophical pondering about why they list one UB when you still need to think for yourself to know what is actually UB, etc.
- 10 different ERRNOs. you need to read all of them in case there is some fundamental info listed there and not elsewhere in the man page you are reading
- some wacky crap like sockaddr_t with casting or an integer split across two parameters (btw socket programming in itself is its own clusterfuck to learn from man pages alone. yes i have done it on one foray into socket programming)
which is why C is not suited for general purpose programming - it has too many edge cases for anyone but the most very strict programmers (most of whom consider themselves to be so are in fact not) who already worked on 3 big programs. you cannot use this for 10s of thousands of lines of CRUD like what gnome or whatever does. the average open source UN*X C program is a buggy mess.then there's also the problem that you can't do anything in UN*X without learning at least 5 different programming languages. this also means you will not have rigid understandings of them all and make common easy to spot bugs. or you can spend hours a day reading about every expression you will invoke and get fired.
one time i had to setup a secure system with some C glue code involving a socket. it took 2 or 3 days to be somewhat sure i am not invoking some kind of UB in this 100 lines of code and that all my file semantics (permissions, timings) were right (also another source of huge complexity for something that should be trivial).
UN*X is a pyramid scheme. whenever you complain about it, someone will say "you're just not man enough to have learned it properly". no matter what you do there will always be this theoretical case of someone more manly than you who has succeeded in UN*X (whatever that means). go try again for another 2 years. of course this is all nonsense, as the averge joe dev or sysadmin in the industry does everything laughably wrong unless there is a meme circulating about how to avoid problem #3527.
did i explain this enough yet? UN*X is an absolute clusterfuck. its not coherently designed in any way what so ever. to set screen blanking parameters on linux, you write some text to the terminal. this is therefore considered """UN*Xy""", because it has something to do with 2 of their major fetishes. this is the level of insanity that is considered normal.
tl;dr you simply cannot learn a UN*X system sufficiently to be able to have a grounded understanding of it as well as being a productive person. perhaps you can dedicate your life to creating a JSON parser after you graduate UN*X and then die of old age.
but this isn't your blog
I would agree that both C and Unix are highly disorganized/decentralized. There is no standard pattern to arguments passed to commands, for example; if this was standardized as much as possible, Unix would become much easier for noobs. And C? 40+ years later and we are still dealing with bad design decisions in it.
But yeah, this isn't your blog. and also, how in the hell did you get burned by unix this badly?