get node links from_socket index value I need to obtain just the index value from node_tree.links[...].from_socket, I am able to see it like for example

# this is example
bpy.data.materials["SomeMat"].node_tree.nodes["SomeNode"].outputs[0]


but I would like to save just the index value [0] to variable...how to? I am lost seeing no option for this... :(

For example there is a way how to find out the name of the ".from_socket" like this:

 bpy.data.materials["SomeMat"].node_tree.links[0].from_socket.name


...and then I get its name, for example output socket called "BSDF". But is there something that returns index number of used output instead of its name as stated above? Cos if I use:

# BTW this gives me exactly what I would normaly needed like 'bpy.data.materials["SomeMat"].node_tree.nodes["SomeNode"].outputs[0]' but this time I need to get only the last index value, it is: [0]
idx = bpy.data.materials["SomeMat"].node_tree.links[0].from_socket


...then the variable is whole object, not just the index value :(

The reason why I need this is because I am copying nodes with their links and all settings from one material to another one, everything work except links, it works OK if there is just one instance of concrete input socket, if there are two of the same name like in Mix Shader (it has two inputs called the same as "shader") then my script does not work right cos it uses socket names instead of their index values like:

links.new(nodes[i.from_node.name].outputs[i.from_socket.name], nodes[i.to_node.name].outputs[i.to_socket.name])


So my new working script would be then:

# see .INDEX is meant just as kind of signature for the index number I am talking about thru all this post
links.new(nodes[i.from_node.name].outputs[i.from_socket.INDEX], nodes[i.to_node.name].outputs[i.to_socket.INDEX])


And all of this just because the most common solution does not work at all, this:

links.new(i.from_socket, i.to_socket)


If I use this then no connections are made...BUT WHY???

BTW I did try to solve it by work around of renaming MixShader socket inputs [1] and [2] that uses the same name of "Shader" to something like "A" and "B" but as soon as I do it Blender crashes right after successful renaming (BTW why in the world they uses the same name at all causing this kind of problems??? gee...)...so no go this way :(

P.S.: I need only script solutions, thanx
One of your examples is - 

links.new(nodes[i.from_node.name].outputs[i.from_socket.name],
          nodes[i.to_node.name].outputs[i.to_socket.name])


Do you notice that you are trying to connect an output socket to an output socket. You would want to connect the from_node.outputs to the to_node.inputs.

Also of note is that as you know the socket names are rarely unique, which is the biggest cause of trouble here, but a socket also has a property called identifier that is a unique name for the node. I don't think you can use it as an array index but by counting your way through all sockets of the node you can find the same identifier and use your count as the index. The socket identifier property was added in 2.66 if you need to watch compatibility.

Another approach to get the socket index number is with something like -

matLinks = bpy.data.materials["SomeMat"].node_tree.links
socketID = matLinks[0].from_socket.path_from_id()[-2:-1]


So path_from_id() will return something like nodes["Mix Shader"].inputs[1] as a string, you can then use array access to get the second last character.

Most nodes only have a few inputs and outputs but to properly handle groups and script nodes which could have more than 10 sockets you would want to search for the last '[' and ']' to define your string extraction.