floating point arithmetic with functions - bash
What these functions do is they curl a json file and parse it, whose output is a number.
function func() {
curl -Ss -H 'Cache-Control: no-cache' url.com/A?limit=2 | jq -r '.
[] | .[] | .blah'
}
function func2() {
curl -Ss -H 'Cache-Control: no-cache' url.com/B2?limit=2 | jq -r '.
[] | .[] | .blah'
}
function func3() {
curl -Ss -H 'Cache-Control: no-cache' url.com/C3?limit=2 | jq -r '.
[] | .[] | .blah'
}
function example() {
"(($(func) * $(func2) * $(func3)))" | bc -l
}
#result is it echoing the numbers, but not actually doing the math.
#echoing .072*.027 in bc, but no math.
So what I'm trying to do is do floating point arithmetic through bash, this is going to be referenced through another function. The only difference is this is with functions. Bash doesn't support floating point arithmetic which is solved through bc.
Example Function numeric output:
#func output
0.072854 #A
0.072855 #B
0.072828 #C
0.072827 #D
#func2 output
0.027873 #A
0.027884 #B
0.027848 #C
0.027847 #D
#func3 output
0.383170 #A
0.383215 #B
0.381858 #C
0.381857 #D
How it works, A * A * A = output1, B * B * B = output2, C * C * C = ouput3
What I've Tried:
function blah() {
echo $((func*func2*func3)) | bc -l
}
#result is "0"
echo "$(func) * $(func2) * $(func3)" | bc -l
#result is:
.072965
.072966
.072925
.002030350008
.027856
.027827
.010633768950
.382371
.380995
.380977
I believe you'll want your function to be like this:
echo "$(func) * $(func2) * $(func3)" | bc -l
EDIT: Since you have multiple values that are output you could put them into arrays, then loop through them and multiply the values:
example() {
a=($(func1))
b=($(func2))
c=($(func3))
for i in {0..3} # set to number of values returned
do
echo "${a[i]} * ${b[i]} * ${c[i]}" | bc -l
done
}
Based on your values the output should be:
.000778087816708140
.000778496988156300
.000774451610799552
.000774411139231933
If your func's return a value then using echo with bc with them should be sufficient.
Related
Trouble making mathematical operations with big hexadecimal numbers on bash
I'm trying to perform multiple mathematical operations with big hexadecimal numbers. In the following code a big random value is given to p and q, both variables are multiplied together making the result the value of n. Then make a subtraction "(n-2)" but when subtracting 2 to n the result seems like being wrong #!/bin/bash generate_random() { head -c 256 /dev/urandom | xxd -p -u -c 256 | tr -d '[:space:]\\' } p="$(generate_random)" q="$(generate_random)" n=$(echo "${p} * ${q}" | tr -d '[:space:]\\') echo "obase=16; ${n} - 2" | bc | tr -d '[:space:]]\\' I'm using this webstie to check the results and so far I haven't managed to get any correct output from my script Value examples: Generated value for p 28DA11279C9BF6B6A93CF1288C63845503D87C17C93554421C3069A5283547CEE4C127F3289BDC03663143808B7318B321B35B25ECC6D48EF60283DA6111104291070E3FBEDBD27A942D2B3630AA8683C6BB4F6F6EE277A24A4C9B93AEEB61D48AC7657FA6E61DC95A8EF133F97C6ED3B285E275487746F070005B2BCDEA9C7C12F294DFCE55BC7013417F8E47CEC605F13AFD5C54A3578BB041278285511248E975FE29F4013CA059599EE95E43E28B886D0651EFDDFF760DBB298096C7CA1A46FE3D119914C23ABA5543C43BE546FA70D7FA36B22DA17210A6CABDCD299751ADEE381A3230E9978946B193AB02921947887A2FC7A5DC84D2193F9CFC865B52 Generated value for q 54DEBA70F8F052F5120B77254EB999E12180241520DC2A12F62F6773992155AEFC5356E3F9B3271FE5AA9D425F7D2CD8233196C98595F993899C31D4063F75A801D1752AD178663E3CDF3CF38CEE1972C861DC6069B787249963D305E4FC970A48E67D3A680CD58F17229379EAE5445603E50E60CF605F1057766EFEAFAA2299CCBC0C4F161815DBD06294E4BBD43EF55F1E2D7544B39279EA4B9114AB9F9D0FC2B46135911CF62FB4A22A615936FDDAD23131B1F0AD2FB94D44C0879B3289530653C4714B2E3F3F9FFD17E92C44FBCE589982F68985207F788FBD1B531C56224E4EDA1F124E6AEC19C949AB396862F0856C435EBAAAB7FFB1251FBEB338676D Result of n 28DA11279C9BF6B6A93CF1288C63845503D87C17C93554421C3069A5283547CEE4C127F3289BDC03663143808B7318B321B35B25ECC6D48EF60283DA6111104291070E3FBEDBD27A942D2B3630AA8683C6BB4F6F6EE277A24A4C9B93AEEB61D48AC7657FA6E61DC95A8EF133F97C6ED3B285E275487746F070005B2BCDEA9C7C12F294DFCE55BC7013417F8E47CEC605F13AFD5C54A3578BB041278285511248E975FE29F4013CA059599EE95E43E28B886D0651EFDDFF760DBB298096C7CA1A46FE3D119914C23ABA5543C43BE546FA70D7FA36B22DA17210A6CABDCD299751ADEE381A3230E9978946B193AB02921947887A2FC7A5DC84D2193F9CFC865B52*54DEBA70F8F052F5120B77254EB999E12180241520DC2A12F62F6773992155AEFC5356E3F9B3271FE5AA9D425F7D2CD8233196C98595F993899C31D4063F75A801D1752AD178663E3CDF3CF38CEE1972C861DC6069B787249963D305E4FC970A48E67D3A680CD58F17229379EAE5445603E50E60CF605F1057766EFEAFAA2299CCBC0C4F161815DBD06294E4BBD43EF55F1E2D7544B39279EA4B9114AB9F9D0FC2B46135911CF62FB4A22A615936FDDAD23131B1F0AD2FB94D44C0879B3289530653C4714B2E3F3F9FFD17E92C44FBCE589982F68985207F788FBD1B531C56224E4EDA1F124E6AEC19C949AB396862F0856C435EBAAAB7FFB1251FBEB338676D Expected value for n d8b187c5754df9d215796bcae5b552e87d4f7a590bb257a208e327cb1e3bf48cbefba07388a0a49f1782f78a232147e9b1137b4eb54611200eab02faa0edd005ee52a33832d391b0aa766fdca712a441a26586fa9418b791e71056117bbf80b07ab68502491a5b70222ad058fdd733b30701f0b46cf7486d8a412096d4a05f43b5c58052baadd51bb08aadf551366513fde427d4fd1ac35778762cd960d3697f4a661b7dda642e5e71284d9fca947171cba5b5e9387cfa078833c3ace7c42baced889cdda8744b021524aec2ed20ef0e0379cf03b206ed0707917c0f38ef66fb79f4198bb1d25c046901b3f54a2910b90ba3b595511042cd682ba38eab459b77b41a37c05d3cffda58346d8dc7bf180ec72aa7b4c4e0cb532c4f374e7bec1e5e970d129dd755a38ca070dd700b5133a3d0c8ba5fbab7c309b94480aa9996d762c1c3cb87170dda878bc9c51db4573681e8dd57db6f4bb1375f386323f643045fef1391498ca7fcca8fe830f6e268db877d7950861a7ab661cb63ab7831934b5a2bdacf53d3c7eac80e1130f786e1b95b5b3f98374ced618a36bb5b3ceab60861ddbb7ae227e9d2abc26931e55483a6a4e891ef54f786519c7250e70a39b821602eb5820fcc4422215452e3a6355140af77697e752aced92cc778e4c6d4df3d8a230a8a8e4756e5f5e347ab0d9bab51f1dc25b5d6099246ae1e2238be3e2dfea
Since the input is in hexadecimal you should also use ibase. #!/bin/bash generate_random() { head -c 256 /dev/urandom | xxd -p -u -c 256 | tr -d '[:space:]\\' } p="$(generate_random)" q="$(generate_random)" n=$(echo "${p} * ${q}" | tr -d '[:space:]\\') echo "obase=16;ibase=16; ${n} - 2" | bc | tr -d '[:space:]]\\' The result in the case you posted is - D8B187C5754DF9D215796BCAE5B552E87D4F7A590BB257A208E327CB1E3BF48CBEFBA07388A0A49F1782F78A232147E9B1137B4EB54611200EAB02FAA0EDD005EE52A33832D391B0AA766FDCA712A441A26586FA9418B791E71056117BBF80B07AB68502491A5B70222AD058FDD733B30701F0B46CF7486D8A412096D4A05F43B5C58052BAADD51BB08AADF551366513FDE427D4FD1AC35778762CD960D3697F4A661B7DDA642E5E71284D9FCA947171CBA5B5E9387CFA078833C3ACE7C42BACED889CDDA8744B021524AEC2ED20EF0E0379CF03B206ED0707917C0F38EF66FB79F4198BB1D25C046901B3F54A2910B90BA3B595511042CD682BA38EAB459B77B41A37C05D3CFFDA58346D8DC7BF180EC72AA7B4C4E0CB532C4F374E7BEC1E5E970D129DD755A38CA070DD700B5133A3D0C8BA5FBAB7C309B94480AA9996D762C1C3CB87170DDA878BC9C51DB4573681E8DD57DB6F4BB1375F386323F643045FEF1391498CA7FCCA8FE830F6E268DB877D7950861A7AB661CB63AB7831934B5A2BDACF53D3C7EAC80E1130F786E1B95B5B3F98374CED618A36BB5B3CEAB60861DDBB7AE227E9D2ABC26931E55483A6A4E891EF54F786519C7250E70A39B821602EB5820FCC4422215452E3A6355140AF77697E752ACED92CC778E4C6D4DF3D8A230A8A8E4756E5F5E347AB0D9BAB51F1DC25B5D6099246AE1E2238BE3E2DFE8 This can be confirmed using python In [1]: hex(0x28DA11279C9BF6B6A93CF1288C63845503D87C17C93554421C3069A5283547CEE4C127F3289BDC03663143808B7318B321B35B25ECC6D48EF60283DA6111104291070E3FBEDBD27A942D2B3630AA8683C6BB4F6F6EE277A24A4C9B93AEEB61D48AC7657F ...: A6E61DC95A8EF133F97C6ED3B285E275487746F070005B2BCDEA9C7C12F294DFCE55BC7013417F8E47CEC605F13AFD5C54A3578BB041278285511248E975FE29F4013CA059599EE95E43E28B886D0651EFDDFF760DBB298096C7CA1A46FE3D119914C23ABA5543 ...: C43BE546FA70D7FA36B22DA17210A6CABDCD299751ADEE381A3230E9978946B193AB02921947887A2FC7A5DC84D2193F9CFC865B52*0x54DEBA70F8F052F5120B77254EB999E12180241520DC2A12F62F6773992155AEFC5356E3F9B3271FE5AA9D425F7D2CD82 ...: 33196C98595F993899C31D4063F75A801D1752AD178663E3CDF3CF38CEE1972C861DC6069B787249963D305E4FC970A48E67D3A680CD58F17229379EAE5445603E50E60CF605F1057766EFEAFAA2299CCBC0C4F161815DBD06294E4BBD43EF55F1E2D7544B3927 ...: 9EA4B9114AB9F9D0FC2B46135911CF62FB4A22A615936FDDAD23131B1F0AD2FB94D44C0879B3289530653C4714B2E3F3F9FFD17E92C44FBCE589982F68985207F788FBD1B531C56224E4EDA1F124E6AEC19C949AB396862F0856C435EBAAAB7FFB1251FBEB3386 ...: 76D-2) Out[1]: '0xd8b187c5754df9d215796bcae5b552e87d4f7a590bb257a208e327cb1e3bf48cbefba07388a0a49f1782f78a232147e9b1137b4eb54611200eab02faa0edd005ee52a33832d391b0aa766fdca712a441a26586fa9418b791e71056117bbf80b07ab68502491a5b70222ad058fdd733b30701f0b46cf7486d8a412096d4a05f43b5c58052baadd51bb08aadf551366513fde427d4fd1ac35778762cd960d3697f4a661b7dda642e5e71284d9fca947171cba5b5e9387cfa078833c3ace7c42baced889cdda8744b021524aec2ed20ef0e0379cf03b206ed0707917c0f38ef66fb79f4198bb1d25c046901b3f54a2910b90ba3b595511042cd682ba38eab459b77b41a37c05d3cffda58346d8dc7bf180ec72aa7b4c4e0cb532c4f374e7bec1e5e970d129dd755a38ca070dd700b5133a3d0c8ba5fbab7c309b94480aa9996d762c1c3cb87170dda878bc9c51db4573681e8dd57db6f4bb1375f386323f643045fef1391498ca7fcca8fe830f6e268db877d7950861a7ab661cb63ab7831934b5a2bdacf53d3c7eac80e1130f786e1b95b5b3f98374ced618a36bb5b3ceab60861ddbb7ae227e9d2abc26931e55483a6a4e891ef54f786519c7250e70a39b821602eb5820fcc4422215452e3a6355140af77697e752aced92cc778e4c6d4df3d8a230a8a8e4756e5f5e347ab0d9bab51f1dc25b5d6099246ae1e2238be3e2dfe8' Not sure what is the calculator you're using but it has a different calculation for some reason.
JSON with jq into bash array / loop through for proper alerting output
I have a JSON result which I want to go through and send an alert, if one or several of the values in the JSON string is smashing thresholds. This bash command: for sat in `docker exec -i storagenode wget -qO - localhost:14002/api/sno | jq .satellites[].id -r`; do docker exec -i storagenode wget -qO - localhost:14002/api/sno/satellite/$sat | jq .id,.audits; done Provides the following (excerpt): "12tRQrMTWUWwzwGh18i7Fqs67kmdhH9t6aToeiwbo5mfS2rUmo" { "auditScore": 1, "suspensionScore": 1, "onlineScore": 0.9974358974358974, "satelliteName": "us2.storj.io:7777" } "1wFTAgs9DP5RSnCqKV1eLf6N9wtk4EAtmN5DpSxcs8EjT69tGE" { "auditScore": 1, "suspensionScore": 1, "onlineScore": 0.9989041005632043, "satelliteName": "saltlake.tardigrade.io:7777" } Now I want to go through the results and e.g. in case, onlineScore drops below 0.9 (or suspensionScore resp. auditScore below 1.0, I want to create a text alert, which also includes the satelliteName. Example: auditScore below threshold: 0.98 for us2.storj.io I guess I can start with the following (from https://unix.stackexchange.com/questions/413878/json-array-to-bash-variables-using-jq), but I do not know, how to loop through the results and how to name and validate the fields: jq -r '.[] | to_entries | .[] | .key + "=" + (.value | #sh)' What the above mentioned statement delivers in subtleties: docker exec -i storagenode wget -qO - localhost:14002/api/sno provides: {"nodeID":"1veqEG5xuBNkt...","wallet":"12345","walletFeatures":["zksync"],"satellites":[{"id":"12tRQrMTWUWwzwGh18i7Fqs67kmdhH9t6aToeiwbo5mfS2rUmo","url":"us2.storj.io:7777","disqualified":null,"suspended":null,"currentStorageUsed":4592556672},{"id":"1wFTAgs9DP5RSnCqKV1eLf6N9wtk4EAtmN5DpSxcs8EjT69tGE","url":"saltlake.tardigrade.io:7777","disqualified":null,"suspended":null,"currentStorageUsed":513269323264},{"id":"121RTSDpyNZVcEU84Ticf2L1ntiuUimbWgfATz21tuvgk3vzoA6","url":"ap1.storj.io:7777","disqualified":null,"suspended":null,"currentStorageUsed":70956116864},{"id":"12EayRS2V1kEsWESU9QMRseFhdxYxKicsiFmxrsLZHeLUtdps3S","url":"us1.storj.io:7777","disqualified":null,"suspended":null,"currentStorageUsed":322340591104},{"id":"12L9ZFwhzVpuEKMUNUqkaTLGzwY9G24tbiigLiXpmZWKwmcNDDs","url":"eu1.storj.io:7777","disqualified":null,"suspended":null,"currentStorageUsed":148740125312},{"id":"12rfG3sh9NCWiX3ivPjq2HtdLmbqCrvHVEzJubnzFzosMuawymB","url":"europe-north-1.tardigrade.io:7777","disqualified":null,"suspended":null,"currentStorageUsed":100681406976}],"diskSpace":{"used":1162257094528,"available":9500000000000,"trash":43196690332,"overused":0},"bandwidth":{"used":31670206976,"available":0},"lastPinged":"2022-01-02T07:55:51.886776586Z","version":"1.45.3","allowedVersion":"1.24.0","upToDate":true,"startedAt":"2021-12-31T00:00:32.209840775Z"} And this one: docker exec -i storagenode wget -qO - localhost:14002/api/sno/satellite/1wFTAgs9DP5RSnCqKV1eLf6N9wtk4EAtmN5DpSxcs8EjT69tGE provides: {"id":"1wFTAgs9DP5RSnCqKV1eLf6N9wtk4EAtmN5DpSxcs8EjT69tGE","storageDaily":[{"atRestTotal":11726579066524.266,"intervalStart":"2022-01-01T00:00:00Z"}],"bandwidthDaily":[{"egress":{"repair":390576640,"audit":7424,"usage":2373615872},"ingress":{"repair":2745100032,"usage":26744320},"delete":0,"intervalStart":"2022-01-01T00:00:00Z"},{"egress":{"repair":143168256,"audit":3584,"usage":786989568},"ingress":{"repair":1034401280,"usage":8107264},"delete":0,"intervalStart":"2022-01-02T00:00:00Z"}],"storageSummary":11726579066524.266,"bandwidthSummary":7508714240,"egressSummary":3694361344,"ingressSummary":3814352896,"currentStorageUsed":513269323264,"audits":{"auditScore":1,"suspensionScore":1,"onlineScore":0.9989041005632043,"satelliteName":"saltlake.tardigrade.io:7777"},"auditHistory":{"score":0.9989041005632043,"windows":[{"windowStart":"2021-12-03T00:00:00Z","totalCount":36,"onlineCount":36},{"windowStart":"2021-12-03T12:00:00Z","totalCount":30,"onlineCount":30},{"windowStart":"2021-12-04T00:00:00Z","totalCount":43,"onlineCount":42},{"windowStart":"2021-12-04T12:00:00Z","totalCount":68,"onlineCount":68},{"windowStart":"2021-12-05T00:00:00Z","totalCount":53,"onlineCount":53},{"windowStart":"2021-12-05T12:00:00Z","totalCount":36,"onlineCount":36},{"windowStart":"2021-12-06T00:00:00Z","totalCount":33,"onlineCount":33},{"windowStart":"2021-12-06T12:00:00Z","totalCount":53,"onlineCount":53},{"windowStart":"2021-12-07T00:00:00Z","totalCount":27,"onlineCount":27},{"windowStart":"2021-12-07T12:00:00Z","totalCount":65,"onlineCount":65},{"windowStart":"2021-12-08T00:00:00Z","totalCount":30,"onlineCount":30},{"windowStart":"2021-12-08T12:00:00Z","totalCount":27,"onlineCount":27},{"windowStart":"2021-12-09T00:00:00Z","totalCount":46,"onlineCount":46},{"windowStart":"2021-12-09T12:00:00Z","totalCount":48,"onlineCount":48},{"windowStart":"2021-12-10T00:00:00Z","totalCount":49,"onlineCount":49},{"windowStart":"2021-12-10T12:00:00Z","totalCount":67,"onlineCount":67},{"windowStart":"2021-12-11T00:00:00Z","totalCount":71,"onlineCount":71},{"windowStart":"2021-12-11T12:00:00Z","totalCount":52,"onlineCount":52},{"windowStart":"2021-12-12T00:00:00Z","totalCount":59,"onlineCount":59},{"windowStart":"2021-12-12T12:00:00Z","totalCount":77,"onlineCount":77},{"windowStart":"2021-12-13T00:00:00Z","totalCount":79,"onlineCount":79},{"windowStart":"2021-12-13T12:00:00Z","totalCount":79,"onlineCount":79},{"windowStart":"2021-12-14T00:00:00Z","totalCount":65,"onlineCount":65},{"windowStart":"2021-12-14T12:00:00Z","totalCount":59,"onlineCount":59},{"windowStart":"2021-12-15T00:00:00Z","totalCount":87,"onlineCount":87},{"windowStart":"2021-12-15T12:00:00Z","totalCount":82,"onlineCount":81},{"windowStart":"2021-12-16T00:00:00Z","totalCount":96,"onlineCount":96},{"windowStart":"2021-12-16T12:00:00Z","totalCount":66,"onlineCount":64},{"windowStart":"2021-12-17T00:00:00Z","totalCount":36,"onlineCount":36},{"windowStart":"2021-12-17T12:00:00Z","totalCount":48,"onlineCount":48},{"windowStart":"2021-12-18T00:00:00Z","totalCount":37,"onlineCount":37},{"windowStart":"2021-12-18T12:00:00Z","totalCount":60,"onlineCount":60},{"windowStart":"2021-12-19T00:00:00Z","totalCount":69,"onlineCount":69},{"windowStart":"2021-12-19T12:00:00Z","totalCount":32,"onlineCount":32},{"windowStart":"2021-12-20T00:00:00Z","totalCount":53,"onlineCount":53},{"windowStart":"2021-12-20T12:00:00Z","totalCount":37,"onlineCount":37},{"windowStart":"2021-12-21T00:00:00Z","totalCount":80,"onlineCount":80},{"windowStart":"2021-12-21T12:00:00Z","totalCount":57,"onlineCount":57},{"windowStart":"2021-12-22T00:00:00Z","totalCount":46,"onlineCount":46},{"windowStart":"2021-12-22T12:00:00Z","totalCount":33,"onlineCount":33},{"windowStart":"2021-12-23T00:00:00Z","totalCount":42,"onlineCount":42},{"windowStart":"2021-12-23T12:00:00Z","totalCount":73,"onlineCount":73},{"windowStart":"2021-12-24T00:00:00Z","totalCount":35,"onlineCount":35},{"windowStart":"2021-12-24T12:00:00Z","totalCount":44,"onlineCount":44},{"windowStart":"2021-12-25T00:00:00Z","totalCount":81,"onlineCount":81},{"windowStart":"2021-12-25T12:00:00Z","totalCount":43,"onlineCount":43},{"windowStart":"2021-12-26T00:00:00Z","totalCount":62,"onlineCount":62},{"windowStart":"2021-12-26T12:00:00Z","totalCount":79,"onlineCount":79},{"windowStart":"2021-12-27T00:00:00Z","totalCount":70,"onlineCount":70},{"windowStart":"2021-12-27T12:00:00Z","totalCount":90,"onlineCount":90},{"windowStart":"2021-12-28T00:00:00Z","totalCount":65,"onlineCount":65},{"windowStart":"2021-12-28T12:00:00Z","totalCount":77,"onlineCount":77},{"windowStart":"2021-12-29T00:00:00Z","totalCount":83,"onlineCount":83},{"windowStart":"2021-12-29T12:00:00Z","totalCount":99,"onlineCount":99},{"windowStart":"2021-12-30T00:00:00Z","totalCount":74,"onlineCount":74},{"windowStart":"2021-12-30T12:00:00Z","totalCount":84,"onlineCount":84},{"windowStart":"2021-12-31T00:00:00Z","totalCount":70,"onlineCount":70},{"windowStart":"2021-12-31T12:00:00Z","totalCount":93,"onlineCount":93},{"windowStart":"2022-01-01T00:00:00Z","totalCount":120,"onlineCount":120},{"windowStart":"2022-01-01T12:00:00Z","totalCount":112,"onlineCount":112},{"windowStart":"2022-01-02T00:00:00Z","totalCount":46,"onlineCount":46}]},"priceModel":{"EgressBandwidth":2000,"RepairBandwidth":1000,"AuditBandwidth":1000,"DiskSpace":150},"nodeJoinedAt":"2021-05-11T20:11:14.910165Z"} Sorry, not sure how to better format the huge json content here in a better way. Thank you for your help. I am not sure how I can modify the output, loop through the results and create the corresponding target output. jq as a tool is new for me and the documentation is not yet self-explanatory for me. UPDATE #1 There is a result for http://localhost:14002/api/sno/satellites, I was not aware of before. The result is: { ... "storageSummary": 6.8624392E13, ... "audits": [ { "auditScore": 1, "suspensionScore": 1, "onlineScore": 0.99743587, "satelliteName": "us2.storj.io:7777" }, { "auditScore": 1, "suspensionScore": 1, "onlineScore": 0.9992917, "satelliteName": "saltlake.tardigrade.io:7777" }, ... { "auditScore": 1, "suspensionScore": 1, "onlineScore": 0.99930555, "satelliteName": "ap1.storj.io:7777" } ] } I think that makes the required handling much easier at the end, right?
Add threshold variables and values using --argjson (preferred over --arg as we talk about numbers), then extract from the .audits object each item that smashes the corresponding threshold using select, format them in a way to carry the actual value and the threshold to be reused in the output, and finally convert those items into an alert string (which will be output as is due to the --raw-output parameter). for sat in `docker exec -i storagenode wget -qO - localhost:14002/api/sno | jq .satellites[].id -r` do docker exec -i storagenode wget -qO - localhost:14002/api/sno/satellite/$sat \ | jq --raw-output \ --argjson auditThreshold 1 \ --argjson suspensionThreshold 1 \ --argjson onlineThreshold 1 \ '.audits | .satelliteName as $name | ( [{auditScore}, $auditThreshold], [{suspensionScore}, $suspensionThreshold], [{onlineScore}, $onlineThreshold] ) | select(.[0][] < .[1]) | "\(.[0] | keys[]) (\(.[0][])) below threshold (\(.[1])) for \($name)" ' done onlineScore (0.9989041005632043) below threshold (1) for saltlake.tardigrade.io:7777 Simplified Demo
You can produce an output which can readable to a while read loop (i.e. while read audit_score suspension_score online_score satellite_name; do) by changing jq .id,.audits to jq -r '.audits | "\(.auditScore) \(.suspensionScore) \(.onlineScore) \(.satelliteName)"'. Use bc as a comparison tool since Bash doesn't support floating points. Also this took me a while to compose but you can compose the messages directly using this: jq -r '.audits | (select(.auditScore < 1) | "auditScore below threshold: \(.auditScore) for \(.satelliteName)"), (select(.suspensionScore < 1) | "suspensionScore below threshold: \(.suspensionScore) for \(.satelliteName)"), (select(.onlineScore < 1) | "onlineScore below threshold: \(.onlineScore) for \(.satelliteName)") ' It should work even with merged outputs from this: docker exec -i storagenode wget -qO - localhost:14002/api/sno | jq .satellites[].id -r | \ xargs -I'{}' docker exec -i storagenode wget -qO - 'localhost:14002/api/sno/satellite/{}'
"bc" external tool into a function
"Despite producing floating point results. Bash does not support other type of arguments than integers, so you need to rather invoke external tools like bc for your math or stick to integers only." 4.5: syntax error: invalid arithmetic operator (error token is ".5") - but the code still seems to work, why? Usually I use the bc external tool to fix it, but now I have a function and I do not know where to use it exactly, can you help me? #!/bin/bash function crossProduct { declare -a v1=("${!1}") declare -a v2=("${!2}") #Note: Can't pass by reference, so the global variable must be used vectResult[0]=$(( (v1[1] * v2[2]) - (v1[2] * v2[1]) )) vectResult[1]=$(( - ((v1[0] * v2[2]) - (v1[2] * v2[0])) )) vectResult[2]=$(( (v1[0] * v2[1]) - (v1[1] * v2[0]) )) } vect1[0]=0.3 vect1[1]=-0.3 vect1[2]=0.1 vect2[0]=0.4 vect2[1]=0.9 vect2[2]=2.3 crossProduct vect1[#] vect2[#] echo ${vectResult[0]} ${vectResult[1]} ${vectResult[2]}
You can pass references, namely as local -n arr=$1: $ function _tmp { local -n arr=$1 for i in ${arr[#]}; do echo $i; done } $ TMP=(1 2 3) $ _tmp TMP 1 2 3 Now to the bc question; it parses a string and returns the value of it. Therefore you should use it as: # make sure you declare vectResult first. function crossProduct { declare -a v1=("${!1}") declare -a v2=("${!2}") vectResult[0]=$( echo "(${v1[1]} * ${v2[2]}) - (${v1[2]} * ${v2[1]}) " | bc) vectResult[1]=$( echo "- ((${v1[0]} * ${v2[2]}) - (${v1[2]} * ${v2[0]}))" | bc ) vectResult[2]=$( echo "(${v1[0]} * ${v2[1]}) - (${v1[1]} * ${v2[0]})" | bc ) } Combining the two as how I would implement it: #!/bin/bash function crossProduct { local -n v1=$1 local -n v2=$2 local result=() # You should remain to use bc because Bash only does integers. result+=($( echo "(${v1[1]} * ${v2[2]}) - (${v1[2]} * ${v2[1]}) " | bc)) result+=($( echo "-((${v1[0]} * ${v2[2]}) - (${v1[2]} * ${v2[0]}))" | bc )) result+=($( echo "(${v1[0]} * ${v2[1]}) - (${v1[1]} * ${v2[0]})" | bc )) echo "${result[#]}" } vect1[0]=0.3 vect1[1]=-0.3 vect1[2]=0.1 vect2[0]=0.4 vect2[1]=0.9 vect2[2]=2.3 vectResult=($(crossProduct vect1 vect2)) echo ${vectResult[0]} ${vectResult[1]} ${vectResult[2]} exit 0 This produces -.6 -.6 .3
how calculated in bash atan2
hello i want to calcul the distance between me and the ISS so this my code i want to print this sentence : The ISS is currently located at -30.1461, -50.7975: 10010km from us! my code : #!/bin/bash pi = 3.14 earthRadiumKm=6371 lat2=48.813875 on2=2.392521 com=$( curl -s 'aletum.jails.simplerezo.com/etna-iss.json' | sed s/\"//g | awk\ -v RS =',' -F: '{print $1 $2 $3}' ) lat1=$( echo $com | cut c-60-66) lon1=$( echo $com | cut c-42-50) dLat=$( echo "($lat2 - $lat1) * $pi / 180" | bc -l) dLat=$( echo "($lon2 - $lon1) * $pi / 180" | bc -l) l1=$( echo "($lat1) * $pi / 180" | bcc -l) l2=$( echo "($lat2) * $pi / 180" | bcc -l) a=$( echo "sinus($dLat / 2) * sinus(dLat / 2) + sinus(dLon / 2) * sinus(dLon / 2) * cosine($l1) * consine($l2) | bc -l) result=$( echo "2 * atan2(sqrt($a), sqrt(1-$a)) * $earthRaduisKm" | bc -1) echo "The ISS is currently located at $dLat, $dLon, : ${result}KM from us!" my Problem is my calcul are false because the result echo 0.6 km and that is impossible i thinks it's because i don't know how to use atan2
Fun little project. I have no idea if your math is right, but your code is quite terribly wrong: no spaces around the = in an assignment: pi = 3.14 => pi=3.14 spelling error for variable names: earthRadiumKm=... => $earthRaduisKm incorrect bc function names incorrect system command names: awk\ -v, bcc -l unclosed quoted string Refactored: #!/bin/bash read lon1 lat1 time < <( curl -s 'aletum.jails.simplerezo.com/etna-iss.json' | jq -r '"\(.iss_position.longitude) \(.iss_position.latitude) \(.timestamp)"' ) lon2=2.392521 lat2=48.813875 { read dLat; read dLon; read result; } < <( bc -l <<END pi = (4*a(1/5) - a(1/239))*4 earthrad = 6371 dlat = ($lat2 - $lat1) * pi/180 dlon = ($lon2 - $lon1) * pi/180 a = s(dlat/2) * s(dlat/2) + s(dlon/2) * s(dlon/2) * c($lat1 * pi/180) * c($lat2 * pi/180) result = 2 * a( sqrt(a) / sqrt(1-a) ) * earthrad dlat dlon result END ) printf "At %s,\n the ISS is currently located at %.4f,%.4f : %.2f KM from us\n" \ "$(date -d "#$time" "+%F %T %Z")" \ "$dLat" "$dLon" "$result" result At 2018-09-12 08:53:32 EDT, the ISS is currently located at 0.5916,-2.2398 : 11296.11 KM from us Notes: repeat, I have no idea if your math is right Process Substitutions to execute some code and read the results into variables. use jq to parse JSON I pushed all the math into a single bc call. bc -l uses s for sine, c for cosine and a for arctan: read the bc man page bc has no arctan2 function I use a formula to get pi a little more precise bc variable names must be all lowercase.
Issue with jq when using in jenkins pipeline
I am having a JSON object x and a variable requiredValue let requiredValue = 5; let x = [ {"score":1}, {"score":2}, {"score":3} } Here using jq first i want to extract all score values and then check if any score value in the object is greater than or equal to requiredValue. Here is what I tried jq -r '.[].score | join(",") | contains([requiredValue])' Suppose if requiredValue is 5 then jq query should return false and if requiredValue is 2 it should return true.
If you split your inputs into two valid JSON documents, rather than having a JavaScript input which is not valid JSON, you could do the following: requiredValue=5 x=' [{"score":1}, {"score":2}, {"score":3}] ' jq -n \ --argjson requiredValue "$requiredValue" \ --argjson x "$x" ' [$x[].score | select(. == $requiredValue)] | any '
The following has been tested with bash: requiredValue=5 x='[ {"score":1}, {"score":2}, {"score":3} ]' jq --argjson requiredValue $requiredValue ' any(.[].score; . >= $requiredValue)' <<< "$x" The result: false