0

I trying to make a program that outputs a triangle of stars in Bash.

Here is what it would look like:

Enter image description here

However, I am getting:

line 8: [: 1: unary operator expected error

Here is my code

#! /bin/bash

read -p "Please input a number for a magical surprise diagram: " input

tri1="1"
tri2="1"

while [ $tri1 -le $input ]; do
    while [ $tri2 -le $tri1 ]; do
        echo -n "*"
        tri2=$( ( $tri2 + 1 ) )
    done

    echo -n ""
    tri1=$( ( $tri1 + 1 ) )
    tri2=1
done

I am a beginner at Bash scripting, so please bear with me as I learn.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3317098
  • 3
  • 1
  • 3

6 Answers6

2

Here's a revised version that takes full advantage of arithmetic evaluation - ((...)) - and expansion $((...)):

#!/usr/bin/env bash

read -p "Please input a number for a magical surprise diagram: " input

tri1=1
tri2=1

while (( tri1 <= input )); do
  while (( tri2 <= tri1 )); do
    printf '*'
    (( ++tri2 ))
  done
  printf '\n'
  (( ++tri1 ))
  tri2=1
done

Also uses the more portable printf, which makes it clearer what is output.


Update:

Simplified version with for ((...;...;...)) loops in lieu of while:

#!/usr/bin/env bash

read -p "Please input a number for a magical surprise diagram: " input

for (( tri1 = 1; tri1 <= input; tri1++ )); do
  for (( tri2 = 1; tri2 <= tri1; tri2++ )); do
    printf '*'
  done
  printf '\n'
done

Even further simplification, replacing the inner loop with a printf trick (borrowed from here):

#!/usr/bin/env bash

read -p "Please input a number for a magical surprise diagram: " input

for (( i = 1; i <= input; i++ )); do
  printf '*%.s' $(seq $i)
  printf '\n'
done
Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thanks a lot, I didnt know you could do this, and ill try to implement it! – user3317098 Feb 17 '14 at 01:27
  • @user3317098: You're welcome; I should also have mentioned `for ((...;...;...))` loops, which are better suited to your task - see my updated answer. – mklement0 Feb 17 '14 at 03:17
0

Just try using quotes

while [ "$tri1" -le "$input" ]; do
  while [ "$tri2" -le " $tri1" ]; do ...

should fix it. Proably you have spaces on $input.

krico
  • 5,723
  • 2
  • 25
  • 28
0

See the difference. This works

echo $(( 1+1 ))

while this one does not

echo $( ( 1+1 ) )
Nik O'Lai
  • 3,586
  • 1
  • 15
  • 17
  • Thanks for the reply, I fixed it and added quotes, but I am still getting line 8: [: : integer expression expected – user3317098 Feb 16 '14 at 23:56
  • Once i've corrected this mistake, I stopped getting this error. – Nik O'Lai Feb 17 '14 at 00:01
  • Another victim of [the Indian space](https://english.stackexchange.com/questions/4645/is-it-ever-correct-to-have-a-space-before-a-question-or-exclamation-mark#comment206109_4645). – Peter Mortensen Oct 05 '21 at 17:15
0

Here is the fix

#! /bin/bash

read -p "Plese input a number for a magical surprise diagram : " input

tri1="1"
tri2="1"

while [ $tri1 -le $input ]; do
   while [ $tri2 -le $tri1 ]; do
   echo -n "*"
   ((tri2=$tri2 + 1 ))    #fixed
   done
  echo -n "" 
    ((tri1= $tri1 + 1 )) #fixed
    tri2=1
  echo ""      # need add a return, otherwise, all output in one line.
done
BMW
  • 42,880
  • 12
  • 99
  • 116
0

The two starting parentheses (( must be a single token for an arithmetic expression, so that it cannot be confused with two nested subshells ( ...; ( ... )).

Between (( and )) you can have any amount of whitespace around the operands and operators of the expression.

The first expression in your code should read either

tri2=$(( tri2 + 1 ))  # POSIX

or

(( tri2=tri2 + 1 ))   # Valid in Bash and ksh93
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Henk Langeveld
  • 8,088
  • 1
  • 43
  • 57
0

I think this is a faster and more readable way to print ranging multiples of a character or string.

#!/bin/bash

read -p "Please input a number for a magical surprise diagram : " input

for i in $(seq $input); do
    c+="*"
    echo "$c"
done

It's important to use quotes here as * will otherwise expand to file names in the current directory.

John B
  • 3,566
  • 1
  • 16
  • 20