Dash est un super environnement d'exécution pour le sous-ensemble POSIX de Bash. Il est portable, hyper rapide, consomme moins de 1 Mo de RAM. Bref un très bon outil.
Par contre, la syntaxe de Bash / Dash est error-prone au possible. D'autant qu'en dehors des outils classiques d'unix (grep, sed, awk, wget/curl) il y a peu de lib qui soient utilisables.
Bref, pour faire de petites choses comme lancer sa JRE ou filtrer des fichiers why not, mais en dehors de ça, ça me fait toujours hésiter.
Et ce matin je découvre que Kotlin peut être utilisé en tant que langage de scripts. Il suffit d'avoir installé dans notre PATH l'utilitaire kscript
disponible ici et nous pouvons commencer à écrire ce genre de choses :
#!/usr/bin/env kscript
println("Hello, World!")
Ensuite un petits chmod u+x
sur notre fichier qui pourra se lancer en tapant :
./mon-script.kts
Et c'est super bien ça !
J'ai eu le besoin de nettoyer des tonnes et des tonnes de features-branches non-mergées et abandonnées dans nos répos Git. J'ai donc écrit un petit script bash qui va lister toutes les branches dont l'âge dépasse le nombre de jours indiqués en paramètre.
Utilisation
# Va lister toutes les branches qui n'ont pas bougées depuis plus de 180 jours
$ git-unused-branches 180
Le script
#!/usr/bin/env bash
if [ "$1" == "" ]; then
echo "Usage: git-too-old-branches <NB_DAYS>"
echo ""
echo "( NB_DAYS The lower age limit filter of branches"
echo " to list"
echo ""
echo "Example"
echo " To list any branches which has not been"
echo " changed since 90 days use :"
echo " git-unused-branches 90"
exit 1
fi
NB_DAYS="${1}"
SECONDS_IN_DAY=86400
TODAY_EPOCH_TIME=$(date +"%s")
## List everything expect
## - Production branches
## - Renovate branches
## - HEAD (master)
list_branches() {
local branches
branches=$(git branch -r | grep -v -E "origin/HEAD|origin/production|origin/renovate" | sed "s/ //" | sort)
echo "${branches}"
}
filter_branch() {
local ageGap
local branch
local branchAge
local maxDays
branch="${1}"
branchAge=$(git log "$branch" -n 1 --format=%ct)
ageGap=$(((TODAY_EPOCH_TIME-branchAge)/SECONDS_IN_DAY))
if (( ${ageGap} > ${NB_DAYS} )); then
echo "$branch is [$ageGap] days old"
fi
}
main() {
local branches
branches=$(list_branches)
for branch in ${branches}
do
filter_branch "${branch}"
done
}
main
En espérant que ça puisse aider certains :P
Les jeunes se feront peut-être avoir, mais les anciens se souviendront de la stratégie EEE et sauront le leur rappeler :
- On Embrasse le standard (Embrace)
- On Étends le standard (Extend)
- On Éteint le standard (Extinguish)
Microchiotte n'est pas l'ami du logiciel libre.
Depuis l'arrivée de WSL, le loup est dans la bergerie. N'utilisons pas les produits Microchiotte quand une variante complètement libre existe.
Et ici, nous avons Linux Mint/Ubuntu et Debian qui couvrent 100% de nos besoins professionnels et 95% de nos besoins personnels. Payer un OS (Operating Spyware) n'est pas le choix le plus judicieux de la terre...
@Animal voici un petit script à mettre dans ton PATH qui te sortira la valeur en hexa directement :
#!/usr/bin/env bash
if [ "${1}" == "" ]; then
echo "Usage : script <PATH_TO_THE_FILE>"
fi
crc=$(cksum -o3 "${1}")
printf "%x\n" ${crc}
Trop bien, c'est exactement ce que je cherchais !!! Et dire que c'était aussi facile... Damned (O__O)
@Oros merci
@Oros j'ai souvent vu que la ligne set -euo pipefail
était recommandée en Bash et je voudrai te poser une question car je crois que le c'est le -e
ou le pipefail
qui ne marchent pas chez moi à cause de ma façon de coder en Bash.
En fait (et je sais que @Animal fait pareil) je créé des fichiers à sourcer et qui ne contiennent que des fonctions. Ces fichiers/bibliothèques peuvent aussi contenir des constantes via un export -r
et surtout, chaque fonction est testée unitairement avec bbtools ou shellunit.
Comme Bash ne permet que de retourner des "exit codes" depuis une fonction, le hack consiste à leur faire imprimer le résultat souhaité via un echo
unique et d'exécuter la fonction de la manière suivante pour récupérer la valeur de retour :
local resultat
resultat=$(ma_fonction "${param_eventuel}")
Donc mon script principale consiste à sourcer les libs dans le bon ordre puis à déclencher une fonction unique, en générale baptisée main()
qui contient la procédure à suivre. Évidemment, cette fonction main()
est purement déclarative et se limite à déléguer les traitements aux fonctions des API sourcées.
Est-ce que tu procèdes comme ça pour écrire un script où est-ce que tu écris les traitements en flat directement dedans ? (Je vais essayer de retrouver le cas ou le set -euo pipefail
plante avec des fonctions)
En deux temps :
1) Installez le paquet webp :
sudo apt install webp
2) Ajoutez ce script à votre PATH (il parcourt récursivement une arborescence à la recherche de fichier .webp
pour les convertir en .png
en supprimant le .webp
d'origine) :
#!/usr/bin/env bash
webp_to_png() {
local files fileName
files=$(find . -name "*.webp")
for file in ${files}
do
if [[ "${file}" == *.webp ]]; then
fileName="${file/webp/png}"
dwebp "${file}" -o "${fileName}"
rm "${file}"
fi
done
}
webp_to_png
Merci j'oublie tout le temps ! (^__^)
Thread d'utilité publique (enfin pour les devs) !
Le résumé en une image :
Merci @Sebsauvage pour l'info.
Un tuto pour installer le Windows Subsystem Linux sous Windows 10.
Problème :
- Vous devez télécharger un très gros fichier.
- Des erreurs réseaux surviennent régulièrement.
- Vous souhaitez reprendre le téléchargement là où il s'est arrêté dès qu'une erreur se produit.
- Vous souhaitez recommencer autant de fois que nécessaire (parce qu'il y aura plusieurs centaines de fois une erreur #RéseauDeQualitayyyy ).
Solution :
Il vous suffit d'utiliser la commande suivante :
OUTPUT_FILE="./mon_fichier"
URL="https://monhost/my-download.file"
wget --continue --tries=inf -O "${OUTPUT_FILE}" "${URL}"
Explication :
--continue
indique à wget de reprendre là où il s'est arrêté.--tries=inf
indique à wget de réessayer autant de fois qu'il le faudra (la limite étant à 20 essais par défaut).-O
indique à wget où écrire le fichier à télécharger.
Aujourd'hui j'ai testé deux Linux Mint : Tricia (19.3) qui est basée sur Ubuntu et LMDE (4) qui est basée sur Debian. Et je ne comprends pas comment marche les variables d'environnement sous LMDE ! Je m'explique, sous une Tricia je peux ajouter des exports dans mon fichier ~/.profile
, typiquement :
# Ajouts en fin de fichier
export JAVA_HOME="..."
...
export PATH="${PATH}:${JAVA_HOME}/bin"
Et que je sois dans un script shell ou dans une console, ces variables sont bien définies avec la bonne valeur. Mieux encore, la modification de $PATH
me permettra d'utiliser les commandes/scripts de démarrage des programmes lorsque j'exécuterai un ALT + F2
; en somme tout marche au poil.
Par contre sous LMDE pas moyen !!
(ノಠ益ಠ)ノ彡┻━┻
Tout ce qui est déclaré dans le ~/.profile
est ignoré par Bash et pourtant je n'ai aucun fichier du type ~/.bash_profile
ou ~/.bash_login
(ndr. pour ceux qui ne le saurait pas, si l'un de ces deux fichiers existe alors le ~/.profile
est ignoré par Bash).
Et c'est très frustrant parce que ce qu'y est défini dans le ~/.bashrc
ne l'est que pour Bash, ce faisant je perds la possibilité de charger des applis via le lanceur ALT + F2
.
Du coup si quelqu'un sait pourquoi et surtout comment y remédier sous LMDE, je veux bien l'info. (◕_◕)
Un très bon tuto fourni par Canonical !
Pour rappel, Dash est une implémentation stricte de la norme POSIX sh, bien plus légère et rapide que Bash ; mais aussi un peu moins fonctionnelle.
Le guide permet de convertir facilement du code Bash en Dash et profiter ainsi de meilleures performances !
En réalité Bash ne possède pas le concept de packages
ou de namespaces
mais il est possible de le reproduire à partir d'une convention de nommage (ce que propose ici Google).
Dans l'idée, il suffit de préfixer toutes les déclarations de fonctions par NOM_DU_PACKAGE::
et de faire la même chose pour les invocations. Par exemple avec un "Hello World!" :
# Définition
CORE::hello() {
echo "Hello ${1}!"
}
export -f CORE::hello
# Usage
CORE::hello "World"
Et ça marche. Par contre impossible de savoir si les double deux-points sont POSIX ou non.
Un énorme mémo pour faire un tas de trucs en bash avec des oneliners. Pour toi @Animal.
Merci à @MamiSama pour le lien
Super cheat sheet ! Merci
La commande est tellement simple : time mon-script.sh
.
Ça marche aussi avec une commande du type time mvn clean install
.
Bref c'est merveilleux.
Exécuter une application en tirant partie du multi-coeur en bash ! Pour toi @Animal !
Via Dooby
Améliorer l'historique Bash de votre Linux.
Via riverbox.