SlideShare a Scribd company logo
* Improved readability, increased fault-tolerance, and more
security
Michael Boelen
michael.boelen@cisofy.com
NLUUG, November 2019
Let's make better*
scripts
Before we begin...
Topics (blue pill)
● Why Shell Scripting?
● Challenges
● Reliability
● Style
● Tools
● Tips and Tricks
4
Topics (red pill)
● When shell (and why not)
● Common mistakes
● More reliable scripts
● and readable...
● Tools for the lazy
● Tips and tricks (no time for that, homework)
5
Michael Boelen
● Open Source since 2003
○ Lynis, Rootkit Hunter
● Business
○ Founder of CISOfy
● Other
○ Blogger at linux-audit.com
○ Content creator at linuxsecurity.expert
6
Let’s do this together
Assumptions
You do Dev || Ops
Linux, BSD, macOS,
Created a script before
Input welcome
Alternatives, feedback
7
Questions
During, at the end, and after
the talk
Share
@mboelen @nluug #nluug
Lynis
● Security: system auditing tool
● 2007
● GPLv3
● 25000+ lines of code
● POSIX
● #!/bin/sh
8
My goals for today
1. Share my knowledge
2. Learn from yours
3. Improve your project (or mine)
9
Why Shell Scripting?
● Powerful
● Quick
● Low on dependencies
Why?
11
What?
Shell scripts = glue
12
Potential
Small scripts can
grow...
… and become an
open source project!
13
Why not?
Challenges and Common Mistakes
Challenge 1: #!/bin/?
17
Shell Pros Cons
sh Portable Not all features available
bash Features Not default on non-Linux
ash/dash Portable and fast Some features missing
ksh Features and fast Not default on Linux
zsh Features Not default
Challenge 1: #!/bin/?
18
Portable sh
Your company only bash
For yourself pick something
Tip: use #!/usr/bin/env bash
Challenge 2: Readability
1 #!/bin/sh
2 var_with_value="red"
3 : ${var_with_value:="blue"}
4 echo "${var_with_value}"
Red or Blue?
19
Challenge 2: Readability
: ${var_with_value:="blue"}
Assign a value when being empty or unset
20
Challenge 3: The Unexpected
#!/bin/sh
filename="test me.txt"
if [ $filename = "test me.txt" ]; then
echo "Filename is correct"
fi
3: [: test: unexpected operator
21
You VS Script
Find the flaw (1)
1 #!/bin/sh
2 chroot=$1
3 rm -rf $chroot/usr/lib/ssl
23
Find the flaw (1)
1 #!/bin/sh
2 chroot=$1
3 rm -rf $chroot/usr/lib/ssl
24
You VS Script
1 - 0
Find the flaw (2)
cat /etc/passwd | grep michael
Goal: retrieve details for user ‘michael’
26
Find the flaw (2)
cat /etc/passwd | grep michael
Better:
grep michael /etc/passwd
grep "^michael:" /etc/passwd
awk -F: '{if($1=="michael") print}' /etc/passwd
getent passwd michael
27
You VS Script
2 - 0
Find the flaw (2)
1 if [-d $i]
2 then
3 echo "$i is a directory! Yay!"
4 else
5 echo "$i is not a directory!"
6 fi
29
Find the flaw (2)
if [ -d $i ]
then
echo "$i is a directory!"
else
echo "$i is not a directory!"
fi
30
You VS Script
3 - 0
Style
Why style matters
● Craftsmanship
● Code reviews
● Bugs
33
Example
Option 1
if [ "${var}" = "text" ]; then
echo "found text"
fi
Option 2
[ "${var}" = "text" ] && echo "found text"
34
Example: be concise?
Option 1
command
if [ $? -ne 0 ]; then
echo "command failed"; exit 1
fi
Option 2
command || { echo "command failed"; exit 1; }
Option 3
if ! command; then echo "command failed"; exit 1; fi
35
var or VAR?
var
Few variables
Few times used
36
VAR
Many variables
Used a lot in script
Commands
Use full options
--quiet instead of -q
--verbose instead -v
etc
37
Style guide
38
Focus on reliability
● Quality
● Do(n’t) make assumptions
● Expect the unexpected
● Consider worst case scenario
● Practice defensive programming
Reliability
40
Defensive programming
Wikipedia:
“is a form of defensive design intended to ensure the
continuing function of a piece of software under unforeseen
circumstances.”
“practices are often used where high availability, safety or
security is needed.”
41
Defenses
Intended operating system?
1 #!/bin/sh
2 if [ ! "$(uname)" = "Linux" ]; then
3 echo "This is not a Linux system and unsupported"
4 exit 1
5 fi
42
Defenses
1 #!/bin/sh
2 if ! $(awk -F= '{if($1 == "NAME" 
3 && $2 ~ /^"CentOS|Ubuntu"$/){rc = 1}; 
4 {exit !rc}}' /etc/os-release 2> /dev/null)
5 then
6 echo "Not CentOS or Ubuntu"
7 exit 1
8 fi
43
Defenses
set -o nounset
(set -u)
Stop at empty variable
Useful for all scripts
44
Defenses
set -o errexit
(set -e)
Exit upon $? -gt 0
Useful for scripts with dependant tasks
Use command || true to allow exception
45
Defenses
set -o pipefail
Useful for scripts with pipes: mysqldump | gzip
(Not POSIX…)
46
Defenses
set -o noglob
(set -f)
Disable globbing (e.g. *)
Useful for scripts which deals with unknown
files
47
Defenses
set -o noclobber
(set -C)
Don’t truncate files, unless >| is used
48
Defenses
1 #!/bin/sh
2 set -o noclobber
3 MYLOG="myscript.log"
4 echo "$(date --rfc-3339=seconds) Start of script" >| ${MYLOG}
5 echo "$(date --rfc-3339=seconds) Something" > ${MYLOG}
11: ./script: cannot create myscript.log: File exists
49
Defenses
Caveat of set options
Enable with - (minus)
Disable with + (plus)
Learn more: The Set Builtin
50
Defenses
Reset localization
export LC_ALL=C
51
Defenses
Execution path
export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
52
Defenses
Use quotes and curly brackets, they are free
[ $foo = "bar" ]
[ "$foo" = "bar" ]
[ "${foo}" = "bar" ]
53
Defenses
Read-only variables
readonly MYVAR="$(hostname -s)"
(Not POSIX…)
54
Defenses
Use traps
trap cleanup INT TERM
trap status USR1
55
Defenses
Untrap
trap - EXIT
56
Defenses
Temporary files
mktemp /tmp/data.XXXXXXXXXX
57
Tools
Linting
59
$ echo 'myvar="TEST' | bash -n
bash: line 1: unexpected EOF while looking for matching `"'
bash: line 2: syntax error: unexpected end of file
17: ./sync-vm-backups-to-usb: Syntax error: "(" unexpected (expecting "then")
Alternative: bash -n script
bash -n
60
sh
● Name?
● Formatting
https://github.com/mvdan/sh
61
sh: POSIX check
$ echo ‘((total=5*7))’ | ./shfmt -p
( (total=5*7))
$ echo 'my_array=(foo bar)' | ./shfmt -p
<standard input>:1:10: arrays are a bash/mksh feature
62
Tool: checkbashisms
$ checkbashisms
Usage: checkbashisms [-n] [-f] [-x] script ...
or: checkbashisms --help
or: checkbashisms --version
This script performs basic checks for the presence of
bashisms
in /bin/sh scripts and the lack of bashisms in /bin/bash
ones.
63
Tool: checkbashisms
possible bashism in /development/lynis/include/functions line 2417 (type):
if type -t typeset; then
possible bashism in /development/lynis/include/functions line 2418 (typeset):
typeset -r $1
64
Tool: ShellCheck
Usage: shellcheck [OPTIONS...] FILES...
--check-sourced Include warnings from sourced files
--color[=WHEN] Use color (auto, always, never)
--include=CODE1,CODE2.. Consider only given types of warnings
--exclude=CODE1,CODE2.. Exclude types of warnings
--format=FORMAT Output format (checkstyle, diff, gcc, json, json1, quiet, tty)
--enable=check1,check2.. List of optional checks to enable (or 'all')
--source-path=SOURCEPATHS Specify path when looking for sourced files ("SCRIPTDIR" for script's dir)
--shell=SHELLNAME Specify dialect (sh, bash, dash, ksh)
--severity=SEVERITY Minimum severity of errors to consider (error, warning, info, style)
--external-sources Allow 'source' outside of FILES
65
Tool: aspell
Grammar check?
66
Tool: Automated testing
Verify expectations
Projects:
● Bash Automated Testing System
● shUnit2
● shpec
67
Conclusions
● Scripts = glue
● Portability or features
● Use other language when needed
● Protect variables
● Check your scripts
68
What questions do you have?
Get connected
● Twitter (@mboelen)
● LinkedIn (Michael Boelen)
69
Tips and Tricks
Useful links
The Open Group Base Specifications Issue 7, 2018 edition
Shell & Utilities
→ Shell Command Language and Utilities
POSIX
73
When to use bash
74
declare/typeset Define a variable type (integer, array)
arrays Data entries
type Describe command
extended globbing Expand file names
for loops with integers for ((i=0; i<10; i++)); do echo $i; done
extended operator if [[ "$1" =~ ^m*$ ]]; then
and more...
[ and [[
[
POSIX
Binary and built-in
Basic comparisons
75
[[
Not POSIX
Keyword
Advanced features
Builtins VS binaries
Differences
● Builtin has lower overhead
● Binary may have more
features
Commands
● enable -a | awk '{print $2}'
● compgen -b
● builtin
● man builtins
● command -v cd
● type -a [
76
Variables
77
POSIX bash ksh
Scope global global, unless ‘local’ is used global or local (based on
function or funcname())
Local overrides global? yes no yes
Variables
Variable possibly unset? Use:
if [ "${name:-}" = "Michael" ]; then
…
fi
78
Screen output
Use printf instead of echo
Output of echo strongly depends on flags and
how it handles escape sequences.
79
Dealing with fatal errors
#!/bin/sh
Fatal() {
msg="${1:-"Unknown error"}"
logger "${msg}"
echo "Fatal error: ${msg}"
# optional: call cleanup?
exit 1
}
command || Fatal "Something happened"
80
Versioning
Semantic versioning!
Major.Minor.Patch
81
Learn more: semver.org
Common issues with software
● No clear license
● Unclear goal
● Authorship
● Versioning
● Changelog missing
82
Changelog
Keep a changelog
● History
● Trust
● Troubleshooting
83
Learn more: keepachangelog.com
Options
--full-throttle-engine, -f
--help, -h, or help
--version, -V
https://github.com/docopt/docopts
84
Learn more: docopt.org
Troubleshooting
Use ‘set’ options for debugging:
-v (verbose) - input is written stderr
-x (xtrace) - show what is executed
85
FOSS tool? Focus areas
Basics
Project description
Tool category
Typical user
License
Author
Language
Keywords
Latest release
86
Quality
Changelog
Popularity
Documentation
Code
Releases
Usage
Installation
Ease of use
Tool review
87
Let’s torn down something!
#!/bin/sh
set -u
hostname=$(hostname)
lockfile=/var/lock/create-backups
timestamp=$(date "+%s")
today=$(date "+%F")
gpgkey=$(gpg --keyid-format LONG --list-keys backup@rootkit.nl 2> /dev/null | awk '/^pub/ { print $2 }' | awk -F/ '{ print $2 }' | head -1)
if [ -z "${hostname}" ]; then echo "Error: no hostname found"; exit 1; fi
if [ ! -z "${lockfile}" ]; then
if [ -f ${lockfile} ]; then
echo "Error: Backup still running. Removing lock file to prevent backup script running next day"
rm ${lockfile}
exit 1
fi
fi
touch ${lockfile}
# Add a daily timestamp to the file for restore checking
echo "${hostname}-${timestamp}-${today}" > /etc/backup.data
88
Useful reads
Bash documentation: https://www.gnu.org/software/bash/manual/html_node/
The Bash Hackers Wiki: https://wiki-dev.bash-hackers.org/
Bash pitfalls: http://mywiki.wooledge.org/BashPitfalls
Cheat sheet: https://devhints.io/bash
Rich’s sh (POSIX shell) tricks: www.etalabs.net/sh_tricks.html
And check out Lynis source code: https://github.com/CISOfy/lynis
89
Credits
Images
Where possible the origin of the used images are included in the slides. Some came without an origin from social media
and therefore have no source. If you are the owner, let us know and we add the source.
90
Lets make better scripts

More Related Content

What's hot

32 shell-programming
32 shell-programming32 shell-programming
32 shell-programming
kayalkarnan
 
Quize on scripting shell
Quize on scripting shellQuize on scripting shell
Quize on scripting shell
lebse123
 
Unix Programming with Perl
Unix Programming with PerlUnix Programming with Perl
Unix Programming with Perl
Kazuho Oku
 

What's hot (20)

Guarding Your Code Against Bugs with Continuous Testing
Guarding Your Code Against Bugs with Continuous TestingGuarding Your Code Against Bugs with Continuous Testing
Guarding Your Code Against Bugs with Continuous Testing
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Penetration testing using python
Penetration testing using pythonPenetration testing using python
Penetration testing using python
 
32 shell-programming
32 shell-programming32 shell-programming
32 shell-programming
 
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
Puppet Camp Chicago 2014: Smoothing Troubles With Custom Types and Providers ...
 
Quize on scripting shell
Quize on scripting shellQuize on scripting shell
Quize on scripting shell
 
Quick start bash script
Quick start   bash scriptQuick start   bash script
Quick start bash script
 
Unix And Shell Scripting
Unix And Shell ScriptingUnix And Shell Scripting
Unix And Shell Scripting
 
Shell Scripting
Shell ScriptingShell Scripting
Shell Scripting
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
OpenGurukul : Language : Shell Scripting
OpenGurukul : Language : Shell ScriptingOpenGurukul : Language : Shell Scripting
OpenGurukul : Language : Shell Scripting
 
Unix Programming with Perl 2
Unix Programming with Perl 2Unix Programming with Perl 2
Unix Programming with Perl 2
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Perl Basics for Pentesters Part 1
Perl Basics for Pentesters Part 1Perl Basics for Pentesters Part 1
Perl Basics for Pentesters Part 1
 
Perl basics for pentesters part 2
Perl basics for pentesters part 2Perl basics for pentesters part 2
Perl basics for pentesters part 2
 
Chap06
Chap06Chap06
Chap06
 
Shell scripting
Shell scriptingShell scripting
Shell scripting
 
Unix Programming with Perl
Unix Programming with PerlUnix Programming with Perl
Unix Programming with Perl
 
Shell & Shell Script
Shell & Shell Script Shell & Shell Script
Shell & Shell Script
 
Interceptors: Into the Core of Pedestal
Interceptors: Into the Core of PedestalInterceptors: Into the Core of Pedestal
Interceptors: Into the Core of Pedestal
 

Similar to Lets make better scripts

Linux Shell Scripting
Linux Shell ScriptingLinux Shell Scripting
Linux Shell Scripting
Raghu nath
 
Unix Shell Scripting
Unix Shell ScriptingUnix Shell Scripting
Unix Shell Scripting
Mustafa Qasim
 

Similar to Lets make better scripts (20)

Bash is not a second zone citizen programming language
Bash is not a second zone citizen programming languageBash is not a second zone citizen programming language
Bash is not a second zone citizen programming language
 
Slides
SlidesSlides
Slides
 
The Unbearable Lightness: Extending the Bash shell
The Unbearable Lightness: Extending the Bash shellThe Unbearable Lightness: Extending the Bash shell
The Unbearable Lightness: Extending the Bash shell
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
One-Liners to Rule Them All
One-Liners to Rule Them AllOne-Liners to Rule Them All
One-Liners to Rule Them All
 
Course 102: Lecture 8: Composite Commands
Course 102: Lecture 8: Composite Commands Course 102: Lecture 8: Composite Commands
Course 102: Lecture 8: Composite Commands
 
Power shell training
Power shell trainingPower shell training
Power shell training
 
Script it
Script itScript it
Script it
 
KT on Bash Script.pptx
KT on Bash Script.pptxKT on Bash Script.pptx
KT on Bash Script.pptx
 
OpenWRT guide and memo
OpenWRT guide and memoOpenWRT guide and memo
OpenWRT guide and memo
 
Nix: What even is it though?
Nix: What even is it though?Nix: What even is it though?
Nix: What even is it though?
 
Bash Shell Scripting
Bash Shell ScriptingBash Shell Scripting
Bash Shell Scripting
 
Raspberry pi Part 25
Raspberry pi Part 25Raspberry pi Part 25
Raspberry pi Part 25
 
Linux Shell Scripting
Linux Shell ScriptingLinux Shell Scripting
Linux Shell Scripting
 
Unix Shell Scripting
Unix Shell ScriptingUnix Shell Scripting
Unix Shell Scripting
 
NYPHP March 2009 Presentation
NYPHP March 2009 PresentationNYPHP March 2009 Presentation
NYPHP March 2009 Presentation
 
InSpec Workshop at Velocity London 2018
InSpec Workshop at Velocity London 2018InSpec Workshop at Velocity London 2018
InSpec Workshop at Velocity London 2018
 
00-Review of Linux Basics
00-Review of Linux Basics00-Review of Linux Basics
00-Review of Linux Basics
 
Continuous Delivery Workshop with Ansible x GitLab CI (2nd+)
Continuous Delivery Workshop with Ansible x GitLab CI (2nd+)Continuous Delivery Workshop with Ansible x GitLab CI (2nd+)
Continuous Delivery Workshop with Ansible x GitLab CI (2nd+)
 
How I hack on puppet modules
How I hack on puppet modulesHow I hack on puppet modules
How I hack on puppet modules
 

More from Michael Boelen

More from Michael Boelen (12)

Getting Traction for (your) Open Source Projects
Getting Traction for (your) Open Source ProjectsGetting Traction for (your) Open Source Projects
Getting Traction for (your) Open Source Projects
 
Linux Security Scanning with Lynis
Linux Security Scanning with LynisLinux Security Scanning with Lynis
Linux Security Scanning with Lynis
 
Dealing with Linux Malware
Dealing with Linux MalwareDealing with Linux Malware
Dealing with Linux Malware
 
Linux Hardening
Linux HardeningLinux Hardening
Linux Hardening
 
Handling of compromised Linux systems
Handling of compromised Linux systemsHandling of compromised Linux systems
Handling of compromised Linux systems
 
Linux Security, from Concept to Tooling
Linux Security, from Concept to ToolingLinux Security, from Concept to Tooling
Linux Security, from Concept to Tooling
 
Linux Security for Developers
Linux Security for DevelopersLinux Security for Developers
Linux Security for Developers
 
Commercieel gaan met je open source project
Commercieel gaan met je open source projectCommercieel gaan met je open source project
Commercieel gaan met je open source project
 
Docker Security - Secure Container Deployment on Linux
Docker Security - Secure Container Deployment on LinuxDocker Security - Secure Container Deployment on Linux
Docker Security - Secure Container Deployment on Linux
 
Docker Security: Are Your Containers Tightly Secured to the Ship?
Docker Security: Are Your Containers Tightly Secured to the Ship?Docker Security: Are Your Containers Tightly Secured to the Ship?
Docker Security: Are Your Containers Tightly Secured to the Ship?
 
How Many Linux Security Layers Are Enough?
How Many Linux Security Layers Are Enough?How Many Linux Security Layers Are Enough?
How Many Linux Security Layers Are Enough?
 
Lynis - Hardening and auditing for Linux, Mac and Unix - NLUUG May 2014
Lynis - Hardening and auditing for Linux, Mac and Unix - NLUUG May 2014Lynis - Hardening and auditing for Linux, Mac and Unix - NLUUG May 2014
Lynis - Hardening and auditing for Linux, Mac and Unix - NLUUG May 2014
 

Recently uploaded

AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
Alluxio, Inc.
 

Recently uploaded (20)

Benefits of Employee Monitoring Software
Benefits of  Employee Monitoring SoftwareBenefits of  Employee Monitoring Software
Benefits of Employee Monitoring Software
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
A Guideline to Zendesk to Re:amaze Data Migration
A Guideline to Zendesk to Re:amaze Data MigrationA Guideline to Zendesk to Re:amaze Data Migration
A Guideline to Zendesk to Re:amaze Data Migration
 
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdfA Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
A Comprehensive Appium Guide for Hybrid App Automation Testing.pdf
 
How To Build a Successful SaaS Design.pdf
How To Build a Successful SaaS Design.pdfHow To Build a Successful SaaS Design.pdf
How To Build a Successful SaaS Design.pdf
 
Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
A Guideline to Gorgias to to Re:amaze Data Migration
A Guideline to Gorgias to to Re:amaze Data MigrationA Guideline to Gorgias to to Re:amaze Data Migration
A Guideline to Gorgias to to Re:amaze Data Migration
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 

Lets make better scripts