{"id":127,"date":"2026-10-12T10:21:35","date_gmt":"2026-10-12T10:21:35","guid":{"rendered":"http:\/\/www.scmgalaxy.com\/tutorials\/2009\/06\/20\/ant-script-with-shell-script\/"},"modified":"2026-10-12T10:21:35","modified_gmt":"2026-10-12T10:21:35","slug":"ant-script-with-shell-script","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/ant-script-with-shell-script\/","title":{"rendered":"How to Run Shell Scripts from Apache Ant (and Set Unix File Permissions Safely)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This guide explains how to combine <strong>Apache Ant<\/strong> with <strong>Unix shell scripts<\/strong> for build tasks such as setting file permissions and processing files. It is aimed at engineers maintaining legacy Ant-based automation who need reliable, repeatable behavior in CI\/CD environments.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Originally published on 2009-06-20; fully revised and updated.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Original post for reference: <a href=\"https:\/\/www.devopsschool.com\/blog\/ant-script-with-shell-script\/\">Ant Script with Shell script, How to run shell script from Ant Script?<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"400\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2009\/06\/ant-script-with-shell-scrip.png\" alt=\"Ant and shell script integration\" class=\"wp-image-4013\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2009\/06\/ant-script-with-shell-scrip.png 600w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2009\/06\/ant-script-with-shell-scrip-300x200.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">What this Ant + shell integration typically solves<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Set execute permissions on scripts before running them.<\/li><li>Call shell utilities that are not available as native Ant tasks.<\/li><li>Run file cleanup or text normalization during builds.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Choose the right approach: native Ant task vs shell execution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Prefer native Ant tasks when they exist, and use shell commands through <code>exec<\/code> when you need OS-specific tooling.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Approach<\/th><th>Best for<\/th><th>Advantages<\/th><th>Caveats<\/th><\/tr><\/thead><tbody><tr><td>Ant <code>chmod<\/code> task<\/td><td>Setting Unix permissions on files\/directories<\/td><td>Portable inside Ant builds; easy to read<\/td><td>Unix-like environments only<\/td><\/tr><tr><td>Ant <code>exec<\/code> calling a script file<\/td><td>Reusable, multi-step shell logic<\/td><td>Keeps shell logic versioned and testable<\/td><td>Requires shell\/runtime on build agent<\/td><\/tr><tr><td>Ant <code>exec<\/code> with inline <code>-c<\/code> command<\/td><td>Small one-liners<\/td><td>Fast to add<\/td><td>Harder to maintain and quote safely<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Execution flow when Ant runs shell commands<\/h2>\n\n\n\n<pre class=\"mermaid\">\nflowchart TD\n    A[Ant target starts] --> B{Native Ant task available}\n    B -- Yes --> C[Run built in Ant task]\n    B -- No --> D[Use exec task]\n    D --> E[Call shell script with args]\n    E --> F[Script returns exit code]\n    F --> G{Exit code is zero}\n    G -- Yes --> H[Continue build]\n    G -- No --> I[Fail build when failonerror is true]\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Set file permissions directly in Ant<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use Ant\u2019s <code>chmod<\/code> task to ensure scripts are executable before calling them.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">project<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"example\"<\/span> <span class=\"hljs-attr\">default<\/span>=<span class=\"hljs-string\">\"fix-perms\"<\/span> <span class=\"hljs-attr\">basedir<\/span>=<span class=\"hljs-string\">\".\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"fix-perms\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">chmod<\/span> <span class=\"hljs-attr\">perm<\/span>=<span class=\"hljs-string\">\"755\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">fileset<\/span> <span class=\"hljs-attr\">dir<\/span>=<span class=\"hljs-string\">\"${basedir}\/scripts\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">include<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"**\/*.sh\"<\/span>\/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">fileset<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">chmod<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">project<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Run a shell script from Ant<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Call a script file (recommended)<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"run-cleanup\"<\/span> <span class=\"hljs-attr\">depends<\/span>=<span class=\"hljs-string\">\"fix-perms\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">exec<\/span> <span class=\"hljs-attr\">executable<\/span>=<span class=\"hljs-string\">\"\/bin\/sh\"<\/span> <span class=\"hljs-attr\">failonerror<\/span>=<span class=\"hljs-string\">\"true\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">arg<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"${basedir}\/scripts\/cleanup-crlf.sh\"<\/span>\/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">arg<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"${basedir}\/input\"<\/span>\/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">exec<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Run a one-liner inline<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">target<\/span> <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"list-text-files\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">exec<\/span> <span class=\"hljs-attr\">executable<\/span>=<span class=\"hljs-string\">\"\/bin\/sh\"<\/span> <span class=\"hljs-attr\">failonerror<\/span>=<span class=\"hljs-string\">\"true\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">arg<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"-c\"<\/span>\/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">arg<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"find '${basedir}\/input' -type f -name '*.txt' -print\"<\/span>\/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">exec<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">target<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Example cleanup script for carriage-return removal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The original post referenced removing special characters. The script below shows a safer pattern for removing carriage returns from text files and replacing files atomically.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php language-bash\"><span class=\"hljs-comment\">#!\/usr\/bin\/env bash<\/span>\nset -euo pipefail\n\nroot_dir=<span class=\"hljs-string\">\"${1:-.}\"<\/span>\n\nfind <span class=\"hljs-string\">\"$root_dir\"<\/span> -type f -print0 | <span class=\"hljs-keyword\">while<\/span> IFS= read -r -d <span class=\"hljs-string\">''<\/span> file; <span class=\"hljs-keyword\">do<\/span>\n  tmp=<span class=\"hljs-string\">\"${file}.tmp\"<\/span>\n  tr -d <span class=\"hljs-string\">'\\r'<\/span> &lt; <span class=\"hljs-string\">\"$file\"<\/span> &gt; <span class=\"hljs-string\">\"$tmp\"<\/span>\n  mv <span class=\"hljs-string\">\"$tmp\"<\/span> <span class=\"hljs-string\">\"$file\"<\/span>\n  <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"updated: $file\"<\/span>\ndone<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs language-bash\">chmod +x scripts\/cleanup-crlf.sh\nant run-cleanup<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Best practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Use <code>failonerror=\"true\"<\/code> so shell failures stop the build immediately.<\/li><li>Keep complex shell logic in versioned <code>.sh<\/code> files, not inline command strings.<\/li><li>Apply cleanup only to known text files to avoid corrupting binaries.<\/li><li>Use Ant properties for paths instead of hardcoding directories.<\/li><li>Validate shell availability (<code>\/bin\/sh<\/code> or <code>bash<\/code>) on each CI runner image.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn practical patterns for combining Apache Ant with shell scripts in Unix-like build environments. This guide covers file permissions, script execution, and safer file-processing examples for legacy CI pipelines.<\/p>\n","protected":false},"author":1,"featured_media":4013,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[12],"tags":[3047,3045,3044,3050,3051,3048,3043,1668,139,2302,3046,3049],"class_list":["post-127","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apache-ant","tag-ant-and-shell-script-commands","tag-ant-script","tag-ant-script-with-shell-script","tag-ant-via-a-shell-script","tag-call","tag-call-shell-script-from-ant-script","tag-how-to-run-shell-script-using-ant","tag-run","tag-scripting","tag-scripts","tag-shell-script","tag-shell-script-using-ant"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=127"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/127\/revisions"}],"predecessor-version":[{"id":78976,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/127\/revisions\/78976"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/4013"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}