i want to match if a distro is debian or is debian based, then it’ll have debian in ID or ID_LIKE vars, so i can switch/case it later (when the distro is debian, the ID_LIKE doesn’t exist)
but i’d like a way to not match the second pattern if the first one is already, i found the regex on the internet but it’s perl-flavour, and that one doesn’t require multiple -e patterns, therefore twice and ||
i’d like to combine it to a single call but weather so hot brain melty
@helene@p.helene.moe@aliss@outerheaven.club @tost@mk.toast.cafe reminds me of that time that i wanted to know if i can detect the OS package manager because i have a script that checks for missing deps and i was going to make it so it called for the packman to install them :hana_lul:
@aliss@tost handling every derivative of arch to check for pacman isn't exactly a solution imo, same for every derivative of debian for dpkg/apt or every derivate of rhel/fedora/centos for dnf/yum
@helene@tost hmmm didn't understand the example entirely, why the package manager example makes u advise me against doing the distro/distro-flavor detection in that way?
@aliss@outerheaven.club @tost@mk.toast.cafe @helene@p.helene.moe you mean bypassing alias? tosti told me how to do that if that's the case, i can dig it for you :akko_thonk:
@schappi@tost@aliss@helene Not just alias, someone could put a random binary or shellscript named `apt` in your PATH and you couldn't tell if it's legit.
@aliss@outerheaven.club I would do probes like thatif grep -qe debian /etc/os-release; then
# debian
elif grep -qe fedora /etc/os-release; then
# fedora
# keep going this way
else
fi or as a shorthandfor myid in debian fedora whatever; do
grep -qe $myid /etc/os-release && break
done
# switch case on $myid, or empty
@aliss@outerheaven.club @schappi@mk.toast.cafe @helene@p.helene.moe mine is like this so I can pass it a list and it only returns 0 if they all exist otherwise you can jus do [ -x "$(command -v \"$1\")" ]
@tost so, first: u’re amazing, can you believe i never thought before of doing it like this?
the var is set after the loop finishes, so you can reuse it later!
i was approaching it something like (1), where my thought process was: first i query the data, then i switch/case, decide what to do after
but your approach (2) goes like the following: you make up a list of your own and run queries, if the query fails more things are queried, but if it goes okay you exit it and save it, you’re using the query as a control flow thing, and because the last success value will be stored in the var loop, you can parse with switch/case later! finally, there’s an extra element in the loop list to not always end with one of the true options!
your (2) is very smart and creative! yes the thought process of it may not be as straightforward as “just query data then parse it”, and you’re using the querying line as something to control the loop but it’s amazing! ???
it made me realise i barely ever use break statements smol brain :02think:
thx a lot u’re great :02_cheer:
(1):
check_distro() {
distro=$(
grep -Po "(?<=^ID_LIKE=).+" /etc/os-release ||
grep -Po "(?<=^ID=).+" /etc/os-release
)
case "$distro" in
"debian"*)
: # do debian-based thing
;;
"fedora"*)
: # do fedora-based thing
;;
*)
: # err distro not supported
;;
esac
}
(2):
check_distro2() {
for distro in debian fedora error
do
grep -qe $distro /etc/os-release && break
done
case "$distro" in
"debian"*)
: # do debian-based thing
;;
"fedora"*)
: # do fedora-based thing
;;
*)
: # err distro not supported
;;
esac
}
@tost i have to confess, while your solution is 19 chars less.. mine is 84 syscalls more efficient.. :acat_hearteyes: (only in fedora, in debian is only 1 syscall more efficient): https://pastebin.com/kn4tLtEX
@tost oh, maybe u could shed me light into a question i have.. why fedora and debian syscall's total numbers are so different even for the same script?
@aliss@outerheaven.club the short version is if the file you're reading is under 4kb, reading it many times over is "free", especially if you're doing it with the same utility
also, when running the tests i first noticed that because in yours debian came first of course some additional syscalls would be in place to test for the first grep, therefore i did `for i in fedora debian...` etc to make it fair
@samgai@vocalounge.cafe@aliss@outerheaven.club mmm that's not a bad point, but that's a very meh way of getting a subshell at that point I'd just do( . /etc/os-release; echo $ID; echo $ID_LIKE; ) | grep -qxe debiansimple substring does carry less weirdness potential though, and generally speaking should be fine in this case, imo
@tost@aliss Please don't do substring matches on data that has a well-defined structure... That's how we wound up with the mess that is HTTP User-Agent, with browser extensions breaking upon the browser reaching version 100, etc...
@aliss@outerheaven.club that's not bad, except you have a mismatch between ID and dist I'd probably do something likegetopts 'd...' # ...
d) dist="$OPTARG" ;; # ....
if [ -z "$dist" ] && [ -f /etc/os-release ]; then
. /etc/os-release
dist="${ID_LIKE:-$ID}"
fiAs one side-note, if this was bash, you could avoid additional leakage using my upvar by slapping the then into a subshell that you source ?
@tost my brain melty a bit with the way you phrased it! haha
i was familiar with this section and i didn’t use - because if it’s set to empty string it wont expand to the second element, and i wanted that so i used :- (if i got it correctly)
if i’ve got it wrong could u clarify / develop further? <33
@aliss@outerheaven.club@samgai@vocalounge.cafe yes, but only because os-release is explicitly shell-compatible I would maybe do it in a subshell but either way, it's fine don't forget to do something like ${ID=$ID_LIKE} or whatever
@tost@samgai yay we found an even shorter solution! another win for lateral thinking :meow_party:
i learned a lot through the way, all thanks to you :02superblush:
don’t forget to do something like ${ID=$ID_LIKE}
hmmm yea you wrote "${ID:=$ID_LIKE}" originally
i’d write "${ID_LIKE:-$ID}“ ie:
if ID_LIKE exists use that, bc is the family, if not use ID, because that will be “mommy distro”, and the :- because i don’t want to override ID_LIKE
@aliss@outerheaven.club@samgai@vocalounge.cafe os-release is a system level file with typically correct permissions (0:0 and 644) so anytime a malicious actor can edit it, it's because they have effective root permissions at which point uh... what are you worried they're going to do that they can't ALREADY do?
@samgai@vocalounge.cafe@aliss@outerheaven.club is os-release actually defined to be shell syntax? I'm under the impression that it's defined to be systemd-compatible ini, which means it could just be completely broken while being "normal" and "expected"
@aliss@tost That looks reasonable to me. It might give you some false negatives, depending on the particular subset of shell syntax that /etc/os-release wants to use.
@aliss@outerheaven.club my approach means users can just set it themselves :nko_3c: and then uses dist I'm tired now though :apensive: messed with unicode all day
if you use $ID after that point, then you lose our on your ID_LIKE preference
.
you mean that if i were to change $ID afterwards and run the conditional again then i’d lose the initial value?
if you use $dist after that point, it’s not going to be set if ID is already set
.
you’re right, so more code, another conditional, would be needed like: if $ID is already set, then put it to dist=.. which would mask the family in a context where the user already has the environ with $ID=kali, then my code wouldn’t do anything still hmmmm :02think:
mebbe like this?:
if [ -z "$ID_LIKE" ] && [ -f /etc/os-release ]
then
. /etc/os-release
else
return 1
fi
dist="${ID_LIKE:-$ID}"
@aliss@outerheaven.club no you don't understand you're setting "dist" if you use $ID after that point, then you lose our on your ID_LIKE preference if you use $dist after that point, it's not going to be set if ID is already set