0

I am not so familiar with bash scripting. I want to echo each line with the proper format role path=... but this for loop does not allow me to do so. It basically prints all in once not go line by line prints. But interestingly when I run vault list database/roles command I am able to see all roles line by line.

How can I resolve this problem?

Code:

for path in $(vault list database/roles);
do
    echo role path=${path}; 
done

Output:

role path=Keys
----
Role-1
Role-2
Role-3
Role-4
Role-5

P.S.: I need to keep everything in the loop as I am going to run this command later on: vault delete database/roles/${path}

Updated: Output for vault list database/roles

Keys ---- Role-1 Role-2 Role-3 Role-4 Role-5

Thanks!

markp-fuso
  • 28,790
  • 4
  • 16
  • 36
cosmos-1905-14
  • 783
  • 2
  • 12
  • 23
  • 1
    Does this answer your question? [How can I loop over the output of a shell command](https://stackoverflow.com/questions/35927760/how-can-i-loop-over-the-output-of-a-shell-command) – gkhaos Apr 26 '21 at 21:38
  • Could be that `vault` prints to stderr. Try `$(vault .... 2>&1)`. But that is odd - where does the `Keys` in `role path=Keys` come from? – KamilCuk Apr 26 '21 at 21:41
  • 2
    In this case, `vault list database/roles | sed 's/^/role path=/` seems like a much simpler solution. BTW, from the way it's behaving now, I suspect you've changed `IFS`, which is generally a bad idea (at least set it back to normal afterward). – Gordon Davisson Apr 26 '21 at 21:42
  • @KamilCuk The first two lines of the output of `vault list ...` is `Keys\n----\n`, but without quotes on the `echo`, it doesn't make any sense to get this output. – William Pursell Apr 26 '21 at 21:43
  • @KamilCuk Anything it prints to stderr would be printed *before* `role path=` – Barmar Apr 26 '21 at 21:43
  • The reason I am trying to do this, I need to keep each role in an array not only print them, because I am planning to run vault delete ${path} command in the loop in order to delete all the roles. @GordonDavisson – cosmos-1905-14 Apr 26 '21 at 22:00
  • @KamilCuk thank you for sharing it. I'd better keep it in the array, because I will use those paths to run this command vault delete database/roles/${path} – cosmos-1905-14 Apr 26 '21 at 22:05
  • please update the question with an additional section showing the results of running `vault list database/roles` at the command line; also, nothing in the current code has anything to do with arrays ... no declaration, no creation, no population, no references soooo, it may help if you update the question with more details on the bigger picture and what you plan on doing with this data, eg, expand on your comment *I need to keep everything in the loop as I am going to run this command later on* – markp-fuso Apr 26 '21 at 22:05
  • the output from `vault list database/roles` is really on a single line? or is each of those items on separate lines? – markp-fuso Apr 26 '21 at 22:09
  • The issue was `IFS` I set previously. I fixed it thanks to @GordonDavisson.Thanks everyone for your time. – cosmos-1905-14 Apr 26 '21 at 22:18

1 Answers1

1

Assuming the output from vault list database/roles looks like:

Keys
----
Role-1
Role-2
Role-3
Role-4
Role-5

OP mentions 'keep it in the array', but there are no signs of an array anywhere in OP's current code; at this point I'm going to assume the intention is to store the output of the vault command in an array.

One idea for storing the roles (aka vault output) in an array:

mapfile -t roles < <(vault list database/roles | tail +3)

This will create and populate an array named roles like such:

$ typeset -p roles
declare -a roles=([0]="Role-1" [1]="Role-2" [2]="Role-3" [3]="Role-4" [4]="Role-5")

From here OP can loop through the array like such:

for ((i=0; i<"${#roles[@]}"; i++))
do
    echo "${i} : ${roles[${i}]}"
done

# or

for i in "${!roles[@]}"
do
    echo "${i} : ${roles[${i}]}"
done

Both of these loops generate:

0 : Role-1
1 : Role-2
2 : Role-3
3 : Role-4
4 : Role-5
markp-fuso
  • 28,790
  • 4
  • 16
  • 36