How to create a stack in a shell script?

bash array
bash list

I need to create a stack in a shell script in order to push values to be processed in a loop. The first requirement is that this must be implemented in a portable manner, as I want to use the script as a portable installer (at least between Unix-like operating systems). The second requirement is that it needs to be able to be altered inside the loop, because new information can appear while the loop is processing an entry, in a recursive manner. The third requirement is that I have more than one line of information per entry (this is mostly a fixed number, and when it isn't it can be calculated based on the first line of information).

My attempt is to use a stack file:


echo "First entry" > stack.txt
echo "More info for the first entry" >> stack.txt
echo "Even more info for the first entry" >> stack.txt

while read ENTRY < stack.txt; do
    INFO2=`tail -n +2 stack.txt | head -n 1`
    INFO3=`tail -n +3 stack.txt | head -n 1`

    tail -n "+4" stack.txt > stack2.txt

    # Process the entry...

    # When we have to push something:
    echo "New entry" > stack.txt
    echo "Info 2" >> stack.txt
    echo "Info 3" >> stack.txt

    # Finally, rebuild stack
    cat stack2.txt >> stack.txt

This works perfectly, except that it feels wrong. Is there a less "hacky" way to do this?

Thanks in advance for any help!

Checkout the section here "Example 27-7. Of empty arrays and empty elements". Specifically the comments say, Above is the 'push' and The 'pop' is:

If you want to encode multiple lines for each element I suggest you base64, or JSON encode the lines. You could also use url encoding or escape the characters using echo.

Since you require the usage of arrays, you may be able to use this example of arrays in sh:

How create a bash script with another bash script?, To prevent variables from being expanded in a here-doc, put quotes around the token. cat <<'EOT' This is a here-doc that contains $variable EOT. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more create html file in shell script

Rather than using a file, it seems like it would be easier to use a directory and store each item in its own file. For example:


push() { echo "$*" > $stackdir/item.$((++count)); }
pop() { 
    if test $count = 0; then
        : > $stackdir/data
        mv $stackdir/item.$((count--)) $stackdir/data
trap 'rm -rf $stackdir' 0
stackdir=$( mktemp -d ${TMPDIR-/tmp}/stack.XXXX )

push some data
push 'another
data point, with
multiple lines'

# Now $stackdir/data contains the popped data
cat $stackdir/data   # Print the most recently item pushed
push yet more data
cat $stackdir/data   # Print 'yet more data'
cat $stackdir/data

A stack implementation, in bash · GitHub, Create a new stack. #. # Usage: stack_new name. #. # Example: stack_new x. function stack_new. {. : ${1?'Missing stack name'}. if stack_exists  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more How to create a graph using shell script

Unfortunately I don't think that solution with cat would work. It might work in Linux, but I am using FreeBSD, and I tried to use cat to import the contents of tempfiles, and it failed constantly.

The problem with cat (at least with FreeBSD) is that it causes the shell to interpret its' output as a literal command, and also trips over certain characters, which again causes problems.

My eventual solution was to convert said tempfiles to holders for variables, and then import them with the source command. This works, but I don't like it; mainly because I have to do some ugly cutting with said in order to prefix the data with the variable name, and encase it in quotes.

So in the data file, you'd have:-


Then in the script, I'd do whatever created my output for the variable, and then to get it into the script would use:-

source datafile

at which point I could use the variable.

Still, even though this doesn't really resemble a stack, it works to store data. I do not like using lone variables in shell scripts if I can avoid them either; mainly because again, it means resorting to ugly substitution hackery, and can become annoying to debug.

awscli shell script to create a cloudformation stack · GitHub, awscli shell script to create a cloudformation stack. #!/​usr/bin/env bash. STACK_NAME=$1. if [ -z "$1" ]. then. echo "No STACK_NAME​  To create a PowerShell script using the Notepad editor on Windows 10, use these steps: Open Start . Search for Notepad , and click the top result to open the app.

This should be pretty cross-platform. It doesn't use arrays, so it can work on older shell versions.

Push(){ let Stack++;eval "Item$Stack=\"$1\"";}
Pop(){ eval "echo -e \$Item$Stack;unset Item$Stack";let Stack--;}
Append(){ Push "`Pop`\n$1";}

Push puts data in variables such as $Item1, $Item2, $Item3, etc. Use it like this:

Push data; Push 'more data'; Push "remember to escape \"quotes\""

Pop by itself destroys the highest-numbered $Item variable after printing its contents. To store the contents in another variable, do this:


Append adds a line to the variable on the top of the stack. For example:

Push "too much is always better than not enough"
Append "but it's almost as bad"

$Stack stores the height of the stack. Since there's no error handling in these functions, you'll need to reset it if there's a stack underflow. Even better, you can just check it to prevent one - don't Pop or Append unless $Stack is 1 or more.

Advanced Examples: pushd and popd, We will implement a stack as an environment variable containing a list of directories The second problem is that if you use pushd in a shell script, it will exit  Shell scripts are popular among system administrators. If you are a system administrator, you can build a collection of custom shell scripts that help you automate tasks you perform often. If a hard drive seems to be getting full, for example, you may want to find all files that exceed some size (say, 1MB) and that have not been accessed in the

Bashisms are disgusting, aren't they? If you need arrays in your program, then you need to use... assembler (kidding)! Well, this is how I implemented the stack in POSIX Shell:


# --------------------
# Stack implementation
# --------------------


# Delete all values from the stack:
stack_clear () {

# To push a value into the stack:
stack_push () {
    local counter
    local cnt
    counter=$(echo -n "${s}" | wc --bytes)
    cnt=$(echo -n "${counter}" | wc --bytes)
    # ----- Internal check begin -----
    check=$(echo -n "${cnt}" | wc --bytes)
    if test "${check}" != "1"
        echo "Internal error: it is real to meet such a long string..."
        exit 2s
    # ----- Internal check end -----
    stk=$(echo -n "${stk}${s}${counter}${cnt}")
    local check
    check=$(echo -n "${stk}" | wc --bytes)
    if test "${check}" -gt "${STACK_MAX_SIZE}"
        echo "Error: stack overflow."
        exit 1

# To pull a value from the stack:
stack_pop () {
    local counter
    local cnt
    if test "${stk}" = ""
        echo "Error: trying to pop from an empty stack."
        exit 1
    cnt=$(echo -n "${stk}" | tail --bytes=1)
    stk=$(echo -n "${stk}" | head --bytes=-1)
    counter=$(echo -n "${stk}" | tail --bytes=${cnt})
    stk=$(echo -n "${stk}" | head --bytes=-${cnt})
    s=$(echo -n "${stk}" | tail --bytes=${counter})
    stk=$(echo -n "${stk}" | head --bytes=-${counter})
    # ----- Internal check begin -----
    local check
    check=$(echo -n "${s}" | wc --bytes)
    if test "${check}" != "${counter}"
        echo "Internal error: the stack is damaged."
        exit 2
    # ----- Internal check end -----

# ---------------
# The entry point
# ---------------

# Push "one", "two", "three" into the stack:
s="one"; stack_push
s="two"; stack_push
s="three"; stack_push

# Extract all the data from the stack:
while test "${stk}" != ""
    echo "${s}"

Linux BASH Shell Script implementing a stack., Linux BASH Shell Script implementing a stack. Thanks Linux Commands for Beginners (Old Duration: 2:14 Posted: 25 Mar 2013 Create the script in a plain text editor such as Notepad and save with a .PS1 file extension (for example, myscript.ps1). Run the script by entering the full path to the script ( c:/scripts/myscript.ps1 ), or if it’s in the current directory, prefix it with a period followed by a backslash ( ./myscript.ps1 ).

How do I create a new empty file in a bash script?, tmpfile=$(mktemp /tmp/abc-script.XXXXXX) : rm "$tmpfile". You can make sure that a file is deleted when the scripts exits (including kills and crashes) by  Apply for Full Stack Developer - Python, Shell Scripting, AWS at CyberCoders Enter your email to apply with your existing LinkedIn profile, or to create a new one. Hmm, we can’t create a profile

How create a temporary file in shell script?, This script wraps the aws cloudformation create-stack command, but lets you create the stacks again and again with different names. The benefit  GOALS: run a powershell script without showing the window (it's ok if it pops up for few seconds). PROBLEM: the script tcplisten.ps1 works just if the window is displayed to the user. All the attempts below don't work.

Tech Debug » Cloudformation stack creation – scripting via bash, Directory Stack Builtins (Bash Reference Manual) Directories are added to the list with the pushd command; the popd command removes directories from the list​. Makes dir be the top of the stack, making it the new current directory as if it 

  • To print line 2 of a file, it is much cleaner to use sed -n 2p rather than piping tail to head.
  • I can't use arrays because it is a specific feature of bash =( I need it to be as much portable as possible
  • @JanitoVaqueiroFerreiraFilho Don't tag your post "bash" if that's the case. zsh, ksh, and tcsh all have arrays, but it isn't part of POSIX.
  • How about using this implementation of arrays in sh. I don't know portable it is...…
  • That is a very interesting idea! =)