Does this joke have a documentation page?
linuxmemes
Hint: :q!
Sister communities:
Community rules (click to expand)
1. Follow the site-wide rules
- Instance-wide TOS: https://legal.lemmy.world/tos/
- Lemmy code of conduct: https://join-lemmy.org/docs/code_of_conduct.html
2. Be civil
- Understand the difference between a joke and an insult.
- Do not harrass or attack users for any reason. This includes using blanket terms, like "every user of thing".
- Don't get baited into back-and-forth insults. We are not animals.
- Leave remarks of "peasantry" to the PCMR community. If you dislike an OS/service/application, attack the thing you dislike, not the individuals who use it. Some people may not have a choice.
- Bigotry will not be tolerated.
3. Post Linux-related content
- Including Unix and BSD.
- Non-Linux content is acceptable as long as it makes a reference to Linux. For example, the poorly made mockery of
sudo
in Windows. - No porn. Even if you watch it on a Linux machine.
4. No recent reposts
- Everybody uses Arch btw, can't quit Vim, <loves/tolerates/hates> systemd, and wants to interject for a moment. You can stop now.
5. π¬π§ Language/ΡΠ·ΡΠΊ/Sprache
- This is primarily an English-speaking community. π¬π§π¦πΊπΊπΈ
- Comments written in other languages are allowed.
- The substance of a post should be comprehensible for people who only speak English.
- Titles and post bodies written in other languages will be allowed, but only as long as the above rule is observed.
6. (NEW!) Regarding public figures
We all have our opinions, and certain public figures can be divisive. Keep in mind that this is a community for memes and light-hearted fun, not for airing grievances or leveling accusations. - Keep discussions polite and free of disparagement.
- We are never in possession of all of the facts. Defamatory comments will not be tolerated.
- Discussions that get too heated will be locked and offending comments removed. Β
Please report posts and comments that break these rules!
Important: never execute code or follow advice that you don't understand or can't verify, especially here. The word of the day is credibility. This is a meme community -- even the most helpful comments might just be shitposts that can damage your system. Be aware, be smart, don't remove France.
unironically, yes
I'm fine with my shell scripts not running on a PDP11.
My only issue is -u
. How do you print help text if your required parameters are always filled. There's no way to test for -z if the shell bails on the first line.
Edit: though I guess you could initialise your vars with bad defaults, and test for those.
#!/bin/bash
set -euo pipefail
if [[ -z "${1:-}" ]]
then
echo "we need an argument!" >&2
exit 1
fi
God I love bash. There's always something to learn.
my logical steps
- #! yup
- if sure!
- [[ -z makes sense
- ${1:-} WHAT IN SATANS UNDERPANTS.... parameter expansion I think... reads docs ... default value! shit that's nice.
it's like buying a really simple generic car then getting excited because it actually has a spare and cupholders.
Yeah, there's also a subtle difference between ${1:-}
and ${1-}
: The first substitutes if 1
is unset or ""
; the second only if 1
is unset. So possibly ${foo-}
is actually the better to use for a lot of stuff, if the empty string is a valid value. There's a lot to bash parameter expansion, and it's all punctuation, which ups the line noise-iness of your scripts.
I don't find it particularly legible or memorable; plus I'm generally not a fan of the variable amount of numbered arguments rather than being able to specify argument numbers and names like we are in practically every other programming language still in common use.
That's good, but if you like to name your arguments first before testing them, then it falls apart
#!/bin/bash
set -euo pipefail
myarg=$1
if [[ -z "${myarg}" ]]
then
echo "we need an argument!" >&2
exit 1
fi
This fails. The solution is to do myarg=${1:-}
and then test
Edit: Oh, I just saw you did that initialisation in the if statement. Take your trophy and leave.
Yeah, another way to do it is
#!/bin/bash
set -euo pipefail
if [[ $# -lt 1 ]]
then
echo "Usage: $0 argument1" >&2
exit 1
fi
i.e. just count arguments. Related, fish
has kind of the orthogonal situation here, where you can name arguments in a better way, but there's no set -u
function foo --argument-names bar
...
end
in the end my conclusion is that argument handling in shells is generally bad. Add in historic workarounds like if [ "x" = "x$1" ]
and it's clear shells have always been Shortcut City
Side note: One point I have to award to Perl for using eq/lt/gt/etc
for string comparisons and ==/</>
for numeric comparisons. In shells it's reversed for some reason? The absolute state of things when I can point to Perl as an example of something that did it better
Perl is the original GOAT! It took a look at shell, realised it could do (slightly) better, and forged its own hacky path!
I was about to say, half the things people write complex shell scripts for, I'll just do in something like Perl, Ruby, Python, even node/TS, because they have actual type systems and readability. And library support. Always situation-dependent though.
I was never a fan of set -e
. I prefer to do my own error handling. But, I never understood why pipefail wasn't the default. A failure is a failure. I would like to know about it!
IIRC if you pipe something do head it will stop reading after some lines and close the pipe, leading to a pipe fail even if everything works correctly
Yeah, I had a silly hack for that. I don't remember what it was. It's been 3-4 years since I wrote bash for a living. While not perfect, I still need to know if a pipeline command failed. Continuing a script after an invisible error, in many cases, could have been catastrophic.
This joke comes with more documentation than most packages.
just use python instead.
- wrap around
subprocess.run()
, to call to system utils - use
pathlib.Path
for file paths and reading/writing to files - use
shutil.which()
to resolve utilities from yourPath
env var
Here's an example of some python i use to launch vscode (and terminals, but that requires dbus
)
from pathlib import Path
from shutil import which
from subprocess import run
def _run(cmds: list[str], cwd=None):
p = run(cmds, cwd=cwd)
# raises an error if return code is non-zero
p.check_returncode()
return p
VSCODE = which('code')
SUDO = which('sudo')
DOCKER = which('docker')
proj_dir = Path('/path/to/repo')
docker_compose = proj_dir / 'docker/'
windows = [
proj_dir / 'code',
proj_dir / 'more_code',
proj_dir / 'even_more_code/subfolder',
]
for w in windows:
_run([VSCODE, w])
_run([SUDO, DOCKER, 'compose', 'up', '-d'], cwd=docker_compose)
Or Rust. Use Command::new() for system commands and Path::new() for paths.
Cool, now pipe something into something else
that is a little more complicated
p.communicate()
will take a string (or bytes) and send it to the stdin of the process, then wait for p
to finish execution
there are ways to stream input into a running process (without waiting for the process to finish), but I don't remember how off the top of my head
from shutil import which
from subprocess import Popen, PIPE, run
from pathlib import Path
LS = which('ls')
REV = which('rev')
ls = run([LS, Path.home()], stdout=PIPE)
p = Popen([REV], stdin=PIPE, stdout=PIPE)
stdout, stderr = p.communicate(ls.stdout)
print(stdout.decode('utf-8'))
Nushell has pipefail by default (plus an actual error system that integrates with status codes) and has actual number values, don't have these problems
nushell is pretty good. I use it for my main shell
although, i still prefer writing utilities in python over nu scripts
Nushell is great as a more powerful scripting language, but a proper language like python is useful too
Powershell is the future
- Windows and office365 admins
I even use powershell as my main scripting language on my Mac now. Iβve come around.
That's sounds terrible honestly
Iβm so used to using powershell to handle collections and pipelines that I find I want it for small scripts on Mac. For instance, I was using ffmpeg to alter a collection of files on my Mac recently. I found it super simple to use Powershell to handle the logic. I could have used other tools, but I didnβt find anything about it terrible.