mirror of
https://github.com/rawiriblundell/wiki.bash-hackers.org
synced 2024-12-25 06:00:41 +01:00
583 lines
37 KiB
Plaintext
583 lines
37 KiB
Plaintext
|
<!DOCTYPE html>
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr" class="no-js">
|
||
|
<head><script type="text/javascript" src="/_static/js/bundle-playback.js?v=TPXmWR5s" charset="utf-8"></script>
|
||
|
<script type="text/javascript" src="/_static/js/wombat.js?v=txqj7nKC" charset="utf-8"></script>
|
||
|
<script type="text/javascript">
|
||
|
__wm.init("http://web.archive.org/web");
|
||
|
__wm.wombat("https://wiki.bash-hackers.org/scripting/basics?do=edit","20221128144910","http://web.archive.org/","web","/_static/",
|
||
|
"1669646950");
|
||
|
</script>
|
||
|
<link rel="stylesheet" type="text/css" href="/_static/css/banner-styles.css?v=S1zqJCYt" />
|
||
|
<link rel="stylesheet" type="text/css" href="/_static/css/iconochive.css?v=qtvMKcIJ" />
|
||
|
<!-- End Wayback Rewrite JS Include -->
|
||
|
|
||
|
<meta charset="UTF-8"/>
|
||
|
<title>The basics of shell scripting [Bash Hackers Wiki]</title>
|
||
|
<script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
|
||
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||
|
<link rel="shortcut icon" href="/web/20221128144910im_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/images/favicon.ico"/>
|
||
|
<link rel="apple-touch-icon" href="/web/20221128144910im_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/images/apple-touch-icon.png"/>
|
||
|
<meta name="generator" content="DokuWiki"/>
|
||
|
<meta name="robots" content="noindex,nofollow"/>
|
||
|
<link type="text/css" rel="stylesheet" href="/web/20221128144910cs_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/assets/bootstrap/default/bootstrap.min.css"/>
|
||
|
<link rel="search" type="application/opensearchdescription+xml" href="/web/20221128144910/https://wiki.bash-hackers.org/lib/exe/opensearch.php" title="Bash Hackers Wiki"/>
|
||
|
<link rel="start" href="/"/>
|
||
|
<link rel="contents" href="/scripting/basics?do=index" title="Sitemap"/>
|
||
|
<link rel="manifest" href="/web/20221128144910/https://wiki.bash-hackers.org/lib/exe/manifest.php"/>
|
||
|
<link rel="alternate" type="application/rss+xml" title="Recent Changes" href="/web/20221128144910/https://wiki.bash-hackers.org/feed.php"/>
|
||
|
<link rel="alternate" type="application/rss+xml" title="Current namespace" href="/web/20221128144910/https://wiki.bash-hackers.org/feed.php?mode=list&ns=scripting"/>
|
||
|
<link rel="alternate" type="text/html" title="Plain HTML" href="/web/20221128144910/https://wiki.bash-hackers.org/_export/xhtml/scripting/basics"/>
|
||
|
<link rel="alternate" type="text/plain" title="Wiki Markup" href="/web/20221128144910/https://wiki.bash-hackers.org/_export/raw/scripting/basics"/>
|
||
|
<link rel="stylesheet" type="text/css" href="/web/20221128144910cs_/https://wiki.bash-hackers.org/lib/exe/css.php?t=bootstrap3&tseed=54923c3deda180f2db5bd755cd8fbf1a"/>
|
||
|
<!--[if gte IE 9]><!-->
|
||
|
<script type="text/javascript">/*<![CDATA[*/var NS='scripting';var JSINFO = {"updatable":1,"userreplace":1,"default_macro_string":"","plugins":{"edittable":{"default columnwidth":""}},"move_renameokay":false,"isadmin":0,"isauth":0,"bootstrap3":{"mode":"source","toc":[],"config":{"collapsibleSections":0,"fixedTopNavbar":1,"showSemanticPopup":0,"sidebarOnNavbar":0,"tagsOnTop":1,"tocAffix":1,"tocCollapseOnScroll":1,"tocCollapsed":0,"tocLayout":"default","useAnchorJS":1,"useAlternativeToolbarIcons":1}},"id":"scripting:basics","namespace":"scripting","ACT":"source","useHeadingNavigation":1,"useHeadingContent":1};
|
||
|
/*!]]>*/</script>
|
||
|
<script type="text/javascript" charset="utf-8" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/exe/jquery.php?tseed=23f888679b4f1dc26eef34902aca964f"></script>
|
||
|
<script type="text/javascript" charset="utf-8" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/exe/js.php?t=bootstrap3&tseed=54923c3deda180f2db5bd755cd8fbf1a"></script>
|
||
|
<script type="text/javascript">/*<![CDATA[*/if (typeof IconifyConfig == 'undefined') { var IconifyConfig = { 'defaultAPI' : '/lib/tpl/bootstrap3/iconify.php?prefix={prefix}&icons={icons}' } }
|
||
|
/*!]]>*/</script>
|
||
|
<script type="text/javascript" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/assets/bootstrap/js/bootstrap.min.js"></script>
|
||
|
<script type="text/javascript" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/assets/anchorjs/anchor.min.js"></script>
|
||
|
<script type="text/javascript" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/assets/typeahead/bootstrap3-typeahead.min.js"></script>
|
||
|
<script type="text/javascript" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/assets/iconify/iconify.min.js"></script>
|
||
|
<script type="text/javascript" src="/web/20221128144910js_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/assets/iconify/plugins/fa.js"></script>
|
||
|
<!--<![endif]-->
|
||
|
<style type="text/css">@media screen { body { margin-top: 65px; } #dw__toc.affix { top: 55px; position: fixed !important; } #dw__toc .nav .nav .nav { display: none; } }</style>
|
||
|
<!--[if lt IE 9]>
|
||
|
<script type="text/javascript" src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||
|
<script type="text/javascript" src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||
|
<![endif]-->
|
||
|
</head>
|
||
|
<body class="default dokuwiki mode_source tpl_bootstrap3 dw-page-on-panel dw-fluid-container" data-page-id="scripting:basics"><div class="dokuwiki">
|
||
|
<header id="dokuwiki__header" class="dw-container dokuwiki container-fluid mx-5">
|
||
|
<!-- navbar -->
|
||
|
<nav id="dw__navbar" class="navbar navbar-fixed-top navbar-default" role="navigation">
|
||
|
|
||
|
<div class="dw-container container-fluid mx-5">
|
||
|
|
||
|
<div class="navbar-header">
|
||
|
|
||
|
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
|
||
|
<span class="icon-bar"></span>
|
||
|
<span class="icon-bar"></span>
|
||
|
<span class="icon-bar"></span>
|
||
|
</button>
|
||
|
|
||
|
<a class="navbar-brand d-flex align-items-center" href="/web/20221128144910/https://wiki.bash-hackers.org/start" accesskey="h" title="Bash Hackers Wiki"><img id="dw__logo" class="pull-left h-100 mr-4" alt="Bash Hackers Wiki" src="/web/20221128144910im_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/images/logo.png"/><div class="pull-right"><div id="dw__title">Bash Hackers Wiki</div></div></a>
|
||
|
</div>
|
||
|
|
||
|
<div class="collapse navbar-collapse">
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<div class="navbar-right" id="dw__navbar_items">
|
||
|
|
||
|
|
||
|
<!-- navbar-searchform -->
|
||
|
<form action="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics" accept-charset="utf-8" class="navbar-form navbar-left search" id="dw__search" method="get" role="search">
|
||
|
<div class="input-group">
|
||
|
<input id="qsearch" autocomplete="off" type="search" placeholder="Search" value="" accesskey="f" name="q" class="form-control" title="[F]"/>
|
||
|
<div class="input-group-btn">
|
||
|
<button class="btn btn-default" type="submit" title="Search">
|
||
|
<span class="iconify" data-icon="mdi:magnify"></span> </button>
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
<input type="hidden" name="do" value="search"/>
|
||
|
</form>
|
||
|
<!-- /navbar-searchform -->
|
||
|
<!-- tools-menu -->
|
||
|
<ul class="nav navbar-nav dw-action-icon" id="dw__tools">
|
||
|
|
||
|
|
||
|
<li class="dropdown">
|
||
|
|
||
|
<a href="" class="dropdown-toggle" data-target="#" data-toggle="dropdown" title="" role="button" aria-haspopup="true" aria-expanded="false">
|
||
|
<span class="iconify" data-icon="mdi:wrench"></span> <span class="hidden-lg hidden-md hidden-sm">Tools</span> <span class="caret"></span>
|
||
|
</a>
|
||
|
|
||
|
<ul class="dropdown-menu tools" role="menu">
|
||
|
|
||
|
<li class="dropdown-header">
|
||
|
<span class="iconify" data-icon="mdi:account"></span> User Tools </li>
|
||
|
|
||
|
<li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=register" title="Register" rel="nofollow" class="menuitem register"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M15 14c-2.67 0-8 1.33-8 4v2h16v-2c0-2.67-5.33-4-8-4m-9-4V7H4v3H1v2h3v3h2v-3h3v-2m6 2a4 4 0 0 0 4-4 4 4 0 0 0-4-4 4 4 0 0 0-4 4 4 4 0 0 0 4 4z"/></svg><span>Register</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=login&sectok=" title="Log In" rel="nofollow" class="menuitem login"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M10 17.25V14H3v-4h7V6.75L15.25 12 10 17.25M8 2h9a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-4h2v4h9V4H8v4H6V4a2 2 0 0 1 2-2z"/></svg><span>Log In</span></a></li>
|
||
|
<li class="divider" role="separator"></li>
|
||
|
|
||
|
|
||
|
<li class="dropdown-header">
|
||
|
<span class="iconify" data-icon="mdi:toolbox"></span> Site Tools </li>
|
||
|
|
||
|
<li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=recent" title="Recent Changes [r]" rel="nofollow" accesskey="r" class="menuitem recent"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M15 13h1.5v2.82l2.44 1.41-.75 1.3L15 16.69V13m4-5H5v11h4.67c-.43-.91-.67-1.93-.67-3a7 7 0 0 1 7-7c1.07 0 2.09.24 3 .67V8M5 21a2 2 0 0 1-2-2V5c0-1.11.89-2 2-2h1V1h2v2h8V1h2v2h1a2 2 0 0 1 2 2v6.1c1.24 1.26 2 2.99 2 4.9a7 7 0 0 1-7 7c-1.91 0-3.64-.76-4.9-2H5m11-9.85A4.85 4.85 0 0 0 11.15 16c0 2.68 2.17 4.85 4.85 4.85A4.85 4.85 0 0 0 20.85 16c0-2.68-2.17-4.85-4.85-4.85z"/></svg><span>Recent Changes</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=media&ns=scripting" title="Media Manager" rel="nofollow" class="menuitem media"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M7 15l4.5-6 3.5 4.5 2.5-3L21 15m1-11h-8l-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2M2 6H0v14a2 2 0 0 0 2 2h18v-2H2V6z"/></svg><span>Media Manager</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=index" title="Sitemap [x]" rel="nofollow" accesskey="x" class="menuitem index"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M3 3h6v4H3V3m12 7h6v4h-6v-4m0 7h6v4h-6v-4m-2-4H7v5h6v2H5V9h2v2h6v2z"/></svg><span>Sitemap</span></a></li>
|
||
|
<li class="divider" role="separator"></li>
|
||
|
|
||
|
|
||
|
<li class="dropdown-header">
|
||
|
<span class="iconify" data-icon="mdi:file-document-outline"></span> Page Tools </li>
|
||
|
|
||
|
<li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=" title="Show page [v]" rel="nofollow" accesskey="v" class="menuitem show"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z"/></svg><span>Show page</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=revisions" title="Old revisions [o]" rel="nofollow" accesskey="o" class="menuitem revs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M11 7v5.11l4.71 2.79.79-1.28-4-2.37V7m0-5C8.97 2 5.91 3.92 4.27 6.77L2 4.5V11h6.5L5.75 8.25C6.96 5.73 9.5 4 12.5 4a7.5 7.5 0 0 1 7.5 7.5 7.5 7.5 0 0 1-7.5 7.5c-3.27 0-6.03-2.09-7.06-5h-2.1c1.1 4.03 4.77 7 9.16 7 5.24 0 9.5-4.25 9.5-9.5A9.5 9.5 0 0 0 12.5 2z"/></svg><span>Old revisions</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=backlink" title="Backlinks" rel="nofollow" class="menuitem backlink"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z"/></svg><span>Backlinks</span></a></li><li class="action"><a href="#dokuwiki__top" title="Back to top [t]" rel="nofollow" accesskey="t" class="menuitem top"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"/></svg><span>Back to top</span></a></li>
|
||
|
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
|
||
|
</ul>
|
||
|
<!-- /tools-menu -->
|
||
|
|
||
|
<ul class="nav navbar-nav">
|
||
|
|
||
|
|
||
|
<li>
|
||
|
<span class="dw__actions dw-action-icon">
|
||
|
<a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=register" title="Register" rel="nofollow" class="menuitem register btn btn-success navbar-btn"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M15 14c-2.67 0-8 1.33-8 4v2h16v-2c0-2.67-5.33-4-8-4m-9-4V7H4v3H1v2h3v3h2v-3h3v-2m6 2a4 4 0 0 0 4-4 4 4 0 0 0-4-4 4 4 0 0 0-4 4 4 4 0 0 0 4 4z"/></svg><span class=""> Register</span></a><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=login&sectok=" title="Log In" rel="nofollow" class="menuitem login btn btn-default navbar-btn"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M10 17.25V14H3v-4h7V6.75L15.25 12 10 17.25M8 2h9a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-4h2v4h9V4H8v4H6V4a2 2 0 0 1 2-2z"/></svg><span class=""> Log In</span></a> </span>
|
||
|
</li>
|
||
|
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
</nav>
|
||
|
<!-- navbar -->
|
||
|
<div align="center">
|
||
|
<script async src="//web.archive.org/web/20221128144910js_/https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||
|
<!-- BHORG_BOTTOM -->
|
||
|
<ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-4658830517838678" data-ad-slot="1603598940"></ins>
|
||
|
<script>
|
||
|
(adsbygoogle = window.adsbygoogle || []).push({});
|
||
|
</script>
|
||
|
</div>
|
||
|
|
||
|
</header>
|
||
|
|
||
|
<a name="dokuwiki__top" id="dokuwiki__top"></a>
|
||
|
|
||
|
<main role="main" class="dw-container pb-5 dokuwiki container-fluid mx-5">
|
||
|
|
||
|
<div id="dokuwiki__pageheader">
|
||
|
|
||
|
|
||
|
<!-- breadcrumbs -->
|
||
|
<nav id="dw__breadcrumbs" class="small">
|
||
|
|
||
|
<hr/>
|
||
|
|
||
|
<div class="dw__youarehere">
|
||
|
<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li>You are here</li><li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a href="/web/20221128144910/https://wiki.bash-hackers.org/start" itemprop="item" title="start"><span itemprop="name"><span class="iconify" data-icon="mdi:home"></span></span></a></li><li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a itemprop="item" href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/start" class="wikilink2" title="scripting:start" rel="nofollow">scripting</a></li><li class="active" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><span itemprop="name"><a itemprop="item" href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics" class="wikilink1" title="scripting:basics">The basics of shell scripting</a></span></li></ol> </div>
|
||
|
|
||
|
<div class="dw__breadcrumbs hidden-print">
|
||
|
<ol class="breadcrumb"><li>Trace</li> </div>
|
||
|
|
||
|
<hr/>
|
||
|
|
||
|
</nav>
|
||
|
<!-- /breadcrumbs -->
|
||
|
|
||
|
<p class="text-right">
|
||
|
<span class="pageId ml-1 label label-primary">scripting:basics</span> </p>
|
||
|
|
||
|
<div id="dw__msgarea" class="small">
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<div class="row">
|
||
|
|
||
|
|
||
|
<article id="dokuwiki__content" class="col-sm-12 col-md-12 " itemscope itemtype="http://schema.org/Article" itemref="dw__license">
|
||
|
|
||
|
|
||
|
<!-- page-tools -->
|
||
|
<nav id="dw__pagetools" class="hidden-print">
|
||
|
<div class="tools panel panel-default">
|
||
|
<ul class="nav nav-stacked nav-pills text-muted">
|
||
|
<li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=" title="Show page [v]" rel="nofollow" accesskey="v" class="menuitem show"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z"/></svg><span>Show page</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=revisions" title="Old revisions [o]" rel="nofollow" accesskey="o" class="menuitem revs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M11 7v5.11l4.71 2.79.79-1.28-4-2.37V7m0-5C8.97 2 5.91 3.92 4.27 6.77L2 4.5V11h6.5L5.75 8.25C6.96 5.73 9.5 4 12.5 4a7.5 7.5 0 0 1 7.5 7.5 7.5 7.5 0 0 1-7.5 7.5c-3.27 0-6.03-2.09-7.06-5h-2.1c1.1 4.03 4.77 7 9.16 7 5.24 0 9.5-4.25 9.5-9.5A9.5 9.5 0 0 0 12.5 2z"/></svg><span>Old revisions</span></a></li><li class="action"><a href="/web/20221128144910/https://wiki.bash-hackers.org/scripting/basics?do=backlink" title="Backlinks" rel="nofollow" class="menuitem backlink"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z"/></svg><span>Backlinks</span></a></li><li class="action"><a href="#dokuwiki__top" title="Back to top [t]" rel="nofollow" accesskey="t" class="menuitem top"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"/></svg><span>Back to top</span></a></li> </ul>
|
||
|
</div>
|
||
|
</nav>
|
||
|
<!-- /page-tools -->
|
||
|
|
||
|
<div class="panel panel-default px-3 py-2" itemprop="articleBody">
|
||
|
<div class="page panel-body">
|
||
|
|
||
|
|
||
|
<div class="dw-content-page "><!-- content --><div class="dw-content"><p>
|
||
|
This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong.
|
||
|
</p>
|
||
|
<div class="editBox" role="application">
|
||
|
|
||
|
<div class="toolbar group">
|
||
|
<div id="draft__status" class="draft__status"></div>
|
||
|
<div id="tool__bar" class="tool__bar"></div>
|
||
|
</div>
|
||
|
<form id="dw__editform" method="post" action="" accept-charset="utf-8" class=" form-inline"><div class="no">
|
||
|
<input type="hidden" name="sectok" value=""/><input type="hidden" name="id" value="scripting:basics"/><input type="hidden" name="rev" value="0"/><input type="hidden" name="date" value="0"/><input type="hidden" name="prefix" value="."/><input type="hidden" name="suffix" value=""/><input type="hidden" name="changecheck" value="c34df8456ea3fc5f8074b2f3a025b298"/><input type="hidden" name="target" value="section"/><textarea name="wikitext" id="wiki__text" dir="auto" class="edit form-control" cols="80" rows="10" tabindex="1" readonly="readonly">
|
||
|
====== The basics of shell scripting ======
|
||
|
|
||
|
{{keywords>bash shell scripting basics learning tutorial}}
|
||
|
|
||
|
===== Script files =====
|
||
|
A shell script usually resides inside a file. The file can be executable, but you can call a Bash script with that filename as a parameter:
|
||
|
<code>
|
||
|
bash ./myfile
|
||
|
</code>
|
||
|
There is **no need to add a boring filename extension** like ''.bash'' or ''.sh''. That is a holdover from UNIX(r), where executables are not tagged by the extension, but by **permissions** (filemode). The file name can be any combination of legal filename characters. Adding a proper filename extension is a convention, nothing else.
|
||
|
<code>
|
||
|
chmod +x ./myfile
|
||
|
</code>
|
||
|
|
||
|
If the file is executable, and you want to use it by calling only the script name, the shebang must be included in the file.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
===== The Shebang =====
|
||
|
The in-file specification of the interpreter of that file, for example:
|
||
|
<code bash>
|
||
|
#!/bin/bash
|
||
|
echo "Hello world..."
|
||
|
</code>
|
||
|
This is interpreted by the kernel ((under specific circumstances, also by the shell itself)) of your system. In general, if a file is executable, but not an executable (binary) program, and such a line is present, the program specified after ''#!'' is started with the scriptname and all its arguments. These two characters ''#'' and ''!'' must be **the first two bytes** in the file!
|
||
|
|
||
|
You can follow the process by using ''echo'' as a fake interpreter:
|
||
|
<code>
|
||
|
#!/bin/echo
|
||
|
</code>
|
||
|
We don't need a script body here, as the file will never be interpreted and executed by "''echo''". You can see what the Operating System does, it calls "''/bin/echo''" with the name of the executable file and following arguments.
|
||
|
<code>
|
||
|
$ /home/bash/bin/test testword hello
|
||
|
/home/bash/bin/test testword hello
|
||
|
</code>
|
||
|
|
||
|
The same way, with ''#!/bin/bash'' the shell "''/bin/bash''" is called with the script filename as an argument. It's the same as executing "''/bin/bash /home/bash/bin/test testword hello''"
|
||
|
|
||
|
If the interpreter can be specified with arguments and how long it can be is system-specific (see [[http://www.in-ulm.de/~mascheck/various/shebang/|#!-magic]]).
|
||
|
When Bash executes a file with a #!/bin/bash shebang, the shebang itself is ignored, since the first character is a hashmark "#", which indicates a comment. The shebang is for the operating system, not for the shell. Programs that don't ignore such lines, may not work as shebang driven interpreters.
|
||
|
|
||
|
<WRAP center round important 60%>
|
||
|
__**Attention:**__When the specified interpreter is unavailable or not executable (permissions), you usually get a "''bad interpreter''" error message., If you get nothing and it fails, check the shebang. Older Bash versions will respond with a "''no such file or directory''" error for a nonexistant interpreter specified by the shebang.
|
||
|
</WRAP>
|
||
|
|
||
|
**Additional note:** When you specify ''#!/bin/sh'' as shebang and that's a link to a Bash, then Bash will run in POSIX(r) mode! See:
|
||
|
* [[scripting:bashbehaviour | Bash behaviour]].
|
||
|
|
||
|
A common method is to specify a shebang like
|
||
|
<code>
|
||
|
#!/usr/bin/env bash
|
||
|
</code>
|
||
|
...which just moves the location of the potential problem to
|
||
|
* the ''env'' utility must be located in /usr/bin/
|
||
|
* the needed ''bash'' binary must be located in ''PATH''
|
||
|
|
||
|
Which one you need, or whether you think which one is good, or bad, is up to you. There is no bulletproof portable way to specify an interpreter. **It's a common misconception that it solves all problems. Period.**
|
||
|
|
||
|
===== The standard filedescriptors =====
|
||
|
Once Initialized, every normal UNIX(r)-program has //at least 3 open files//:
|
||
|
|
||
|
* **stdin**: standard input
|
||
|
* **stdout**: standard output
|
||
|
* **stderr**: standard error output
|
||
|
|
||
|
Usually, they're all connected to your terminal, stdin as input file (keyboard), stdout and stderr as output files (screen). When calling such a program, the invoking shell can change these filedescriptor connections away from the terminal to any other file (see redirection).
|
||
|
Why two different output filedescriptors? It's convention to send error messages and warnings to stderr and only program output to stdout. This enables the user to decide if they want to see nothing, only the data, only the errors, or both - and where they want to see them.
|
||
|
|
||
|
When you write a script:
|
||
|
* always read user-input from ''stdin''
|
||
|
* always write diagnostic/error/warning messages to ''stderr''
|
||
|
|
||
|
To learn more about the standard filedescriptors, especially about redirection and piping, see:
|
||
|
* [[howto:redirection_tutorial | An illustrated redirection tutorial]]
|
||
|
|
||
|
===== Variable names =====
|
||
|
It's good practice to use lowercase names for your variables, as shell and system-variable names are usually all in UPPERCASE. However, you should avoid naming your variables any of the following (incomplete list!):
|
||
|
|''BASH''|''BASH_ARGC''|''BASH_ARGV''|''BASH_LINENO''|''BASH_SOURCE''|''BASH_VERSINFO''|
|
||
|
|''BASH_VERSION''|''COLUMNS''|''DIRSTACK''|''DISPLAY''|''EDITOR''|''EUID''|
|
||
|
|''GROUPS''|''HISTFILE''|''HISTFILESIZE''|''HISTSIZE''|''HOME''|''HOSTNAME''|
|
||
|
|''IFS''|''LANG''|''LANGUAGE''|''LC_ALL''|''LINES''|''LOGNAME''|
|
||
|
|''LS_COLORS''|''MACHTYPE''|''MAILCHECK''|''OLDPWD''|''OPTERR''|''OPTIND''|
|
||
|
|''OSTYPE''|''PATH''|''PIPESTATUS''|''PPID''|''PROMPT_COMMAND''|''PS1''|
|
||
|
|''PS2''|''PS4''|''PS3''|''PWD''|''SHELL''|''SHELLOPTS''|
|
||
|
|''SHLVL''|''TERM''|''UID''|''USER''|''USERNAME''|''XAUTHORITY''|
|
||
|
This list is incomplete. **The safest way is to use all-lowercase variable names.**
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
===== Exit codes =====
|
||
|
Every program you start terminates with an exit code and reports it to the operating system. This exit code can be utilized by Bash. You can show it, you can act on it, you can control script flow with it.
|
||
|
The code is a number between 0 and 255. Values from 126 to 255 are reserved for use by the shell directly, or for special purposes, like reporting a termination by a signal:
|
||
|
* **126**: the requested command (file) was found, but can't be executed
|
||
|
* **127**: command (file) not found
|
||
|
* **128**: according to ABS it's used to report an invalid argument to the exit builtin, but I wasn't able to verify that in the source code of Bash (see code 255)
|
||
|
* **128 + N**: the shell was terminated by the signal N
|
||
|
* **255**: wrong argument to the exit builtin (see code 128)
|
||
|
|
||
|
The lower codes 0 to 125 are not reserved and may be used for whatever the program likes to report.
|
||
|
A value of 0 means **successful** termination, a value not 0 means **unsuccessful** termination. This behavior (== 0, != 0) is also what Bash reacts to in some flow control statements.
|
||
|
|
||
|
An example of using the exit code of the program ''grep'' to check if a specific user is present in /etc/passwd:
|
||
|
<code bash>
|
||
|
if grep ^root /etc/passwd; then
|
||
|
echo "The user root was found"
|
||
|
else
|
||
|
echo "The user root was not found"
|
||
|
fi
|
||
|
</code>
|
||
|
|
||
|
A common decision making command is "''test''" or its equivalent "''[''". But note that, when calling test with the name "''[''", the square brackets are not part of the shell syntax, the left bracket **is** the test command!
|
||
|
|
||
|
<code bash>
|
||
|
if [ "$mystring" = "Hello world" ]; then
|
||
|
echo "Yeah dude, you entered the right words..."
|
||
|
else
|
||
|
echo "Eeeek - go away..."
|
||
|
fi
|
||
|
</code>
|
||
|
Read more about [[commands:classictest | the test command]]
|
||
|
|
||
|
A common exit code check method uses the "''||''" or "''&&''" operators. This lets you execute a command based on whether or not the previous command completed successfully:
|
||
|
<code bash>
|
||
|
grep ^root: /etc/passwd >/dev/null || echo "root was not found - check the pub at the corner."
|
||
|
which vi && echo "Your favourite editor is installed."
|
||
|
</code>
|
||
|
|
||
|
Please, when your script exits on errors, provide a "FALSE" exit code, so others can check the script execution.
|
||
|
|
||
|
===== Comments =====
|
||
|
In a larger, or complex script, it's wise to comment the code. Comments can help with debugging or tests. Comments start with the # character (hashmark) and continue to the end of the line:
|
||
|
<code bash>
|
||
|
#!/bin/bash
|
||
|
# This is a small script to say something.
|
||
|
echo "Be liberal in what you accept, and conservative in what you send" # say something
|
||
|
</code>
|
||
|
The first thing was already explained, it's the so-called shebang, for the shell, **only a comment**. The second one is a comment from the beginning of the line, the third comment starts after a valid command. All three syntactically correct.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
==== Block commenting ====
|
||
|
To temporarily disable complete blocks of code you would normally have to prefix every line of that block with a # (hashmark) to make it a comment. There's a little trick, using the pseudo command '':'' (colon) and input redirection. The '':'' does nothing, it's a pseudo command, so it does not care about standard input. In the following code example, you want to test mail and logging, but not dump the database, or execute a shutdown:
|
||
|
<code bash>
|
||
|
#!/bin/bash
|
||
|
# Write info mails, do some tasks and bring down the system in a safe way
|
||
|
echo "System halt requested" | mail -s "System halt" netadmin@example.com
|
||
|
logger -t SYSHALT "System halt requested"
|
||
|
|
||
|
##### The following "code block" is effectively ignored
|
||
|
: <<"SOMEWORD"
|
||
|
/etc/init.d/mydatabase clean_stop
|
||
|
mydatabase_dump /var/db/db1 /mnt/fsrv0/backups/db1
|
||
|
logger -t SYSHALT "System halt: pre-shutdown actions done, now shutting down the system"
|
||
|
shutdown -h NOW
|
||
|
SOMEWORD
|
||
|
##### The ignored codeblock ends here
|
||
|
</code>
|
||
|
What happened? The '':'' pseudo command was given some input by redirection (a here-document) - the pseudo command didn't care about it, effectively, the entire block was ignored.
|
||
|
|
||
|
The here-document-tag was quoted here **to avoid substitutions** in the "commented" text! Check [[syntax:redirection#tag_heredoc | redirection with here-documents]] for more
|
||
|
|
||
|
|
||
|
===== Variable scope =====
|
||
|
|
||
|
|
||
|
In Bash, the scope of user variables is generally //global//. That means, it does **not** matter whether a variable is set in the "main program" or in a "function", the variable is defined everywhere.
|
||
|
|
||
|
Compare the following //equivalent// code snippets:
|
||
|
<code bash>
|
||
|
myvariable=test
|
||
|
echo $myvariable
|
||
|
</code>
|
||
|
|
||
|
<code bash>
|
||
|
myfunction() {
|
||
|
myvariable=test
|
||
|
}
|
||
|
|
||
|
myfunction
|
||
|
echo $myvariable
|
||
|
</code>
|
||
|
|
||
|
In both cases, the variable ''myvariable'' is set and accessible from everywhere in that script, both in functions and in the "main program".
|
||
|
|
||
|
**__Attention:__** When you set variables in a child process, for example a //subshell//, they will be set there, but you will **never** have access to them outside of that subshell. One way to create a subshell is the pipe. It's all mentioned in a small article about [[scripting:processtree | Bash in the processtree]]!
|
||
|
|
||
|
==== Local variables ====
|
||
|
|
||
|
Bash provides ways to make a variable's scope //local// to a function:
|
||
|
* Using the ''local'' keyword, or
|
||
|
* Using ''declare'' (which will //detect// when it was called from within a function and make the variable(s) local).
|
||
|
<code bash>
|
||
|
myfunc() {
|
||
|
local var=VALUE
|
||
|
|
||
|
# alternative, only when used INSIDE a function
|
||
|
declare var=VALUE
|
||
|
|
||
|
...
|
||
|
}
|
||
|
</code>
|
||
|
|
||
|
The //local// keyword (or declaring a variable using the ''declare'' command) tags a variable to be treated //completely local and separate// inside the function where it was declared:
|
||
|
|
||
|
<code bash>
|
||
|
foo=external
|
||
|
|
||
|
printvalue() {
|
||
|
local foo=internal
|
||
|
|
||
|
echo $foo
|
||
|
}
|
||
|
|
||
|
|
||
|
# this will print "external"
|
||
|
echo $foo
|
||
|
|
||
|
# this will print "internal"
|
||
|
printvalue
|
||
|
|
||
|
# this will print - again - "external"
|
||
|
echo $foo
|
||
|
</code>
|
||
|
|
||
|
==== Environment variables ====
|
||
|
|
||
|
The environment space is not directly related to the topic about scope, but it's worth mentioning.
|
||
|
|
||
|
Every UNIX(r) process has a so-called //environment//. Other items, in addition to variables, are saved there, the so-called //environment variables//. When a child process is created (in Bash e.g. by simply executing another program, say ''ls'' to list files), the whole environment //including the environment variables// is copied to the new process. Reading that from the other side means: **Only variables that are part of the environment are available in the child process.**
|
||
|
|
||
|
A variable can be tagged to be part of the environment using the ''export'' command:
|
||
|
<code bash>
|
||
|
# create a new variable and set it:
|
||
|
# -> This is a normal shell variable, not an environment variable!
|
||
|
myvariable="Hello world."
|
||
|
|
||
|
# make the variable visible to all child processes:
|
||
|
# -> Make it an environment variable: "export" it
|
||
|
export myvariable
|
||
|
</code>
|
||
|
|
||
|
Remember that the //exported// variable is a **copy**. There is no provision to "copy it back to the parent." See the article about [[scripting:processtree | Bash in the process tree]]!</textarea>
|
||
|
<div id="wiki__editbar" class="editBar">
|
||
|
<div id="size__ctl">
|
||
|
</div>
|
||
|
</div>
|
||
|
</div></form>
|
||
|
</div>
|
||
|
</div><!-- /content --></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="small text-right">
|
||
|
|
||
|
<span class="docInfo">
|
||
|
<ul class="list-inline"><li><span class="iconify text-muted" data-icon="mdi:file-document-outline"></span> <span title="scripting/basics.txt">scripting/basics.txt</span></li><li><span class="iconify text-muted" data-icon="mdi:calendar"></span> Last modified: <span title="2019/08/30 09:07">2019/08/30 09:07</span></li><li class="text-muted">by <bdi>ersen</bdi></li></ul> </span>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</article>
|
||
|
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</main>
|
||
|
|
||
|
<footer id="dw__footer" class="dw-container py-5 dokuwiki container-fluid">
|
||
|
<hr/>
|
||
|
<div align="center">
|
||
|
<h3><a target="_blank" href="http://web.archive.org/web/20221128144910/http://www.performing-databases.com/">This site is supported by Performing Databases - your experts for database administration</a></h3>
|
||
|
</div>
|
||
|
<hr/>
|
||
|
<div align="center">
|
||
|
<script async src="//web.archive.org/web/20221128144910js_/https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
|
||
|
<!-- BHORG_BOTTOM -->
|
||
|
<ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-4658830517838678" data-ad-slot="1603598940"></ins>
|
||
|
<script>
|
||
|
(adsbygoogle = window.adsbygoogle || []).push({});
|
||
|
</script>
|
||
|
</div>
|
||
|
|
||
|
<!-- footer -->
|
||
|
<div class="dw-container small container-fluid mx-5">
|
||
|
|
||
|
|
||
|
<div class="footer-dw-title">
|
||
|
<div class="media">
|
||
|
<div class="media-left">
|
||
|
<img src="/web/20221128144910im_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/images/logo.png" alt="Bash Hackers Wiki" class="media-object" style="height:32px"/>
|
||
|
</div>
|
||
|
<div class="media-body">
|
||
|
<div class="row">
|
||
|
<div class="col-sm-2">
|
||
|
<h4 class="media-heading">Bash Hackers Wiki</h4>
|
||
|
<p>
|
||
|
</p>
|
||
|
</div>
|
||
|
<div class="col-sm-10">
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="footer-license row">
|
||
|
<hr/>
|
||
|
<div id="dw__license" class="col-sm-6">
|
||
|
<p>
|
||
|
<a href="http://web.archive.org/web/20221128144910/http://www.gnu.org/licenses/fdl-1.3.html" title="GNU Free Documentation License 1.3" target="" itemscope itemtype="http://schema.org/CreativeWork" itemprop="license" rel="license" class="license"><img src="/web/20221128144910im_/https://wiki.bash-hackers.org/lib/tpl/bootstrap3/images/license/gnufdl.png" width="24" height="24" alt="gnufdl"/> </a> </p>
|
||
|
<p class="small">
|
||
|
Except where otherwise noted, content on this wiki is licensed under the following license:<br/><a href="http://web.archive.org/web/20221128144910/http://www.gnu.org/licenses/fdl-1.3.html" title="GNU Free Documentation License 1.3" target="" itemscope itemtype="http://schema.org/CreativeWork" itemprop="license" rel="license" class="license">GNU Free Documentation License 1.3</a> </p>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-6">
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
<!-- /footer -->
|
||
|
</footer>
|
||
|
|
||
|
<a href="#dokuwiki__top" class="back-to-top hidden-print btn btn-default" title="skip to content" accesskey="t">
|
||
|
<span class="iconify" data-icon="mdi:chevron-up"></span> </a>
|
||
|
|
||
|
<div id="screen__mode"> <span class="visible-xs-block"></span>
|
||
|
<span class="visible-sm-block"></span>
|
||
|
<span class="visible-md-block"></span>
|
||
|
<span class="visible-lg-block"></span>
|
||
|
</div>
|
||
|
|
||
|
<img src="/web/20221128144910im_/https://wiki.bash-hackers.org/lib/exe/indexer.php?id=scripting%3Abasics&1669646976" width="2" height="1" alt=""/>
|
||
|
</div>
|
||
|
|
||
|
</body>
|
||
|
</html>
|
||
|
<!--
|
||
|
FILE ARCHIVED ON 14:49:10 Nov 28, 2022 AND RETRIEVED FROM THE
|
||
|
INTERNET ARCHIVE ON 11:35:19 Apr 14, 2023.
|
||
|
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
|
||
|
|
||
|
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
|
||
|
SECTION 108(a)(3)).
|
||
|
-->
|
||
|
<!--
|
||
|
playback timings (ms):
|
||
|
captures_list: 162.546
|
||
|
exclusion.robots: 0.124
|
||
|
exclusion.robots.policy: 0.116
|
||
|
cdx.remote: 0.055
|
||
|
esindex: 0.009
|
||
|
LoadShardBlock: 122.43 (3)
|
||
|
PetaboxLoader3.datanode: 124.081 (4)
|
||
|
load_resource: 234.57
|
||
|
PetaboxLoader3.resolve: 198.104
|
||
|
-->
|