JaedenRuiner JaedenRuiner - 1 year ago 127
Git Question

Git Bash and new line

People have often asked why I am not such a fan of linux, well here'e why.
In Windows programming a \n is a \n. period. there is no other interpretation. But in linux bash, who knows what you're going to get.

for example:
every thing i look up online says that:

will split on new line.
so will someone please explain to me why this:

local OIFS="$IFS"
local status=$(git status --porcelain 2> /dev/null)
#I even added this just in case:
status=$( status )
#but no matter what length is always 1
local length=${#status[@]}
echo $length

echos the value of 1 when I know for certain that the git status in this repository returns 7 lines of data?
I've tried, $(echo -en "\n\b"), I've tried just "\n" (which seems funny enough to split on new line but also on just the letter n.)
It's like standardization doesn't exist in linux. I can run the same script several times and get different results.

All I want, is a script that takes the porcelain results of git status, splits it on the new line, and then splits it on the space for each line.
this would create a an array of arrays, that look like:

[0] "M","modfile.cs"
[1] "A","addfile.cs"
[2] "??","newfile.cs"

but IFS does not seem to EVER want to handle a carriage return. In other commands I was able to fix this because they had -printf or --pretty arguments that I could change the split char on. But get status i only newline and so far, bash script can't split on new line.

Any ideas?
Jaeden "Sifo Dyas" al'Raec Ruiner

PS tell your editor that I decide what is code, not it.

Answer Source

I think you're getting confused by bash syntax (which, admittedly, is a bit of a mess). The problem is that var=(some stuff) and var=$(some stuff) do completely different things. var=(some stuff) sets var as an array. var=$(some stuff) runs some stuff as a command, captures its output, and stores that in var as a plain string, not an array (and not split with IFS). If you want to create an array from the output of a command, you need to combine both: arrayvar=( $(some stuff) ). So this should work:

local OIFS="$IFS"
local status=( $(git status --porcelain 2> /dev/null) )
#but no matter what length is always 1
local length=${#status[@]}
echo $length

Note that I moved the IFS=$OIFS command earlier in the sequence, because the splitting you want it to control happens in the status=( stuff to be split ) line, and having a nonstandard IFS set any longer than necessary can cause weird effects. Also, I completely removed status=$( status ), since it discards the previous value of the variable (/array) status, and replaces it with the output of the command (not variable) status, treated as a plain string (rather than an array). Not what you wanted at all.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download