-1

I'm new to bash scripting and trying to learn.

I have a variable $temp, that contains what I get from an API call, which is a long list of SHA1 hashes. I want to take what is in $temp and create an array that I can loop through and compare each entry to a string I have defined. Somehow, I can not seem to get it to work. The array I create always only contains only one element. It is like the rest of the string in $temp is being ignored.

I have tried multiple approaches, and can't get anything working the way I want it to. Here's the code snippet:

temp=$(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash")
echo "Temp is: $temp"

declare -A myArr
read myArr <<<$temp

echo ${myArr[@]}

echo ${myArr[0]}

echo ${myArr[1]}

When I run this, I get a full list of hashes, when I echo $temp (line 2), something like this:

"Temp is: 002C3CADF9FC86069F09961B10E0EDEFC45:1 003BE35BD9466D19258E79C8665AFB072F6:1 0075B2ADF782F9677BDDF8CC5778900D986:8 00810352C02B145FF304FCBD5BEF4F7AA9F:1 013720F40B99D6BCF6F08BD7271523EBB49:1 01C894A55EBCB6048A745B37EC2D989F102:1 030B46D53696C8889910EE0F9EB42CEAE97:4 03126B56153F0564F4A6ED6E734604C67E8:2 043196099707FCB0C01F8C2111086A92A0B:1 0452CABBEF8438F358F0BD8089108D0910E:5 0490255B206A2C0377EBD080723BF72DDAE:2 05AD1141C41237E061460DB5CA5412C1A48:4 05C1D058E4439F8F005EFB32E7553E6AA5B:1 067AF515CC712AC4ACA012311979DBC7C9A:2 ... and so on.."

But the

echo ${myArr[@]}

echo ${myArr[0]}

echo ${myArr[1]}

returns (first value is ${myArr[@]}, second is ${myArr[0]}, and last one is an empty line, indicating that there is no value at array position 1):

002C3CADF9FC86069F09961B10E0EDEFC45:1 002C3CADF9FC86069F09961B10E0EDEFC45:1

I hope someone can help with this.

Thanks a lot in advance!

ssh
  • 15
  • 6

2 Answers2

1
declare -A myArr # creates an associative array (hash)
declare -a myArr # creates an array

Neither is necessary here. read can create the array for you. See help declare and help read.


temp=$(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash")

# -a: assign the words read to sequential indices of the array
read -a myArr <<<"$temp"
declare -p myArr

Output:

declare -a myArr=([0]="002C3CADF9FC86069F09961B10E0EDEFC45:1" [1]="003BE35BD9466D19258E79C8665AFB072F6:1" [2]="0075B2ADF782F9677BDDF8CC5778900D986:8" [3]="00810352C02B145FF304FCBD5BEF4F7AA9F:1" [4]="013720F40B99D6BCF6F08BD7271523EBB49:1" [5]="01C894A55EBCB6048A745B37EC2D989F102:1" [6]="030B46D53696C8889910EE0F9EB42CEAE97:4" [7]="03126B56153F0564F4A6ED6E734604C67E8:2" [8]="043196099707FCB0C01F8C2111086A92A0B:1" [9]="0452CABBEF8438F358F0BD8089108D0910E:5" [10]="0490255B206A2C0377EBD080723BF72DDAE:2" [11]="05AD1141C41237E061460DB5CA5412C1A48:4" [12]="05C1D058E4439F8F005EFB32E7553E6AA5B:1" [13]="067AF515CC712AC4ACA012311979DBC7C9A:2")

Cyrus
  • 84,225
  • 14
  • 89
  • 153
0

Assuming ...

$(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash")

Returns ...

002C3CADF9FC86069F09961B10E0EDEFC45:1
003BE35BD9466D19258E79C8665AFB072F6:1
0075B2ADF782F9677BDDF8CC5778900D986:8
00810352C02B145FF304FCBD5BEF4F7AA9F:1
013720F40B99D6BCF6F08BD7271523EBB49:1
01C894A55EBCB6048A745B37EC2D989F102:1
030B46D53696C8889910EE0F9EB42CEAE97:4
03126B56153F0564F4A6ED6E734604C67E8:2
043196099707FCB0C01F8C2111086A92A0B:1
0452CABBEF8438F358F0BD8089108D0910E:5
0490255B206A2C0377EBD080723BF72DDAE:2
05AD1141C41237E061460DB5CA5412C1A48:4
05C1D058E4439F8F005EFB32E7553E6AA5B:1
067AF515CC712AC4ACA012311979DBC7C9A:2

Then assign this to an array by wrapping in a set of parens:

# unset current variable
$ unset myArr

# no need to issue a `declare`; the `myArr=( ... )` will automatically create `myArr` as a normal integer-indexed array
$ myArr=( $(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash") )

# verify array contents:
$ typeset myArr
declare -a myarr=([0]="002C3CADF9FC86069F09961B10E0EDEFC45:1" [1]="003BE35BD9466D19258E79C8665AFB072F6:1" [2]="0075B2ADF782F9677BDDF8CC5778900D986:8" [3]="00810352C02B145FF304FCBD5BEF4F7AA9F:1" [4]="013720F40B99D6BCF6F08BD7271523EBB49:1" [5]="01C894A55EBCB6048A745B37EC2D989F102:1" [6]="030B46D53696C8889910EE0F9EB42CEAE97:4" [7]="03126B56153F0564F4A6ED6E734604C67E8:2" [8]="043196099707FCB0C01F8C2111086A92A0B:1" [9]="0452CABBEF8438F358F0BD8089108D0910E:5" [10]="0490255B206A2C0377EBD080723BF72DDAE:2" [11]="05AD1141C41237E061460DB5CA5412C1A48:4" [12]="05C1D058E4439F8F005EFB32E7553E6AA5B:1" [13]="067AF515CC712AC4ACA012311979DBC7C9A:2")

Assuming OP wants to populate the array from the variable $temp, and assuming the white space in $temp consists of linefeeds and not spaces:

$ mapfile -t myArr <<< "${temp}"
$ typeset -p myArr
declare -a x=([0]="002C3CADF9FC86069F09961B10E0EDEFC45:1" [1]="003BE35BD9466D19258E79C8665AFB072F6:1" [2]="0075B2ADF782F9677BDDF8CC5778900D986:8" [3]="00810352C02B145FF304FCBD5BEF4F7AA9F:1" [4]="013720F40B99D6BCF6F08BD7271523EBB49:1" [5]="01C894A55EBCB6048A745B37EC2D989F102:1" [6]="030B46D53696C8889910EE0F9EB42CEAE97:4" [7]="03126B56153F0564F4A6ED6E734604C67E8:2" [8]="043196099707FCB0C01F8C2111086A92A0B:1" [9]="0452CABBEF8438F358F0BD8089108D0910E:5" [10]="0490255B206A2C0377EBD080723BF72DDAE:2" [11]="05AD1141C41237E061460DB5CA5412C1A48:4" [12]="05C1D058E4439F8F005EFB32E7553E6AA5B:1" [13]="067AF515CC712AC4ACA012311979DBC7C9A:2")
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • 1
    Thtre is no need to replace the newlines with spaces. You might want to make sure there are no DOS carriage returns in the value, though (`tr -d '\015'`) – tripleee Apr 02 '21 at 16:03
  • `array=$( $(anything) )` is not good practice -- you don't want a line containing only `*` to be replaced with a list of filenames in the current directory, f/e. Much better to use `mapfile` as suggested at the end of this practice. – Charles Duffy Apr 02 '21 at 16:06
  • and as in triplee's comment, I don't know what `tr` is accomplishing here; newlines and spaces are both present in the default value of `IFS`. – Charles Duffy Apr 02 '21 at 16:07
  • triplee/Charles Duffy - thanks for the comment re: `tr` ... was running my tests under `cygwin/bash` and for some reason the `\n`'s were being picked as part of the data; have updated the answer – markp-fuso Apr 02 '21 at 16:13