Managing paths - directories in shell and scripts

0

Been using unix cygwin for a time and added many tools recently, command line and scripting are much more familiar. Scripting and programming is my number one goal and 100k dollar question? I am not weened from windows yet though.

The post here -> solved a users dilemma! did a lot to make using / switching paths and directories easier. Better than opening notepad++ and doing it! Specifically this command

# cd "$(cygpath -u 'c:\Program Files\')" 

by ben. works on the fly in bash for me so as to allow building scripts efficiently.

Can someone for programming sake break it down piecemeal?

I noticed there's 2 commands and - quotes and the parenthesis are 'separating' the $ , which I assume is a variable place holder???

I always end up thinking it is shell built in doing it, the easy answer, but still need to find out. And the double quotes outside are for what, while inner singe quotes are for space and literal interpretations by shell.

Exactly what is the shell doing start- to finish? Running a debug could be option I believe, how do I do that to show outputs? Thanks for the response.

Last, I did not mention what I used to try to convert paths. Saw stuff for sed strings but never worked due to complexity, this is much simpler.

Sircutz

Posted 2016-09-13T16:35:27.163

Reputation: 1

Answers

1

A common misconception is that the $ sign means variable. It actually signals bash to perform an expansion (There are cases where variables can be referenced without the $ sign, but I won't get too off topic).

When bash sees the $ sign in front of a variable, it will replace the $VAR with the value (of the variable) and then execute the entire line.

In your example, bash will be doing a command substitution/expansion. Between the parenthesis is a command, bash will execute that command first, take the output and replace the $(command) with it, then execute the cd command.

You can observe this behavior by looking at a trace. Execute your script using bash -x or put set -o xtrace below the header of your script. Example:

#!/bin/bash
set -o xtrace

This will output the exact commands that bash is executing during the scripts which means after substitutions/expansions have taken place.

As for the quotes, they are not 100% necessary, but there can be situations in which the command in your example would not work properly. And that is if there are any spaces in the path returned by cygpath -u 'c:\Program Files\'. Bash command arguments are usually delimited by spaces, and without the quotes, bash will interpret those spaces as a delimiter and not a literal space (also the reason why there are single quotes around the path specified for the cygpath command).

For example, if the returned path was c:\user\Documents and Settings, with out quotes bash would read the command as cd c:\user\Documents and Settings, in which it will think that c:\user\Documents, and, and Settings are all arguments to be passed to the cd command. This is a problem because the cd command is only supposed to have one argument.

Double quotes around the $ substitution prevents space interpretation.

Chip Shadd

Posted 2016-09-13T16:35:27.163

Reputation: 150

Thank you so much. My question was answered 100 percent. Reading man pages for bash , xtrace or set for complete details, that will be very valuable. Still work to do on it , as I am not using scripts , everything typed , and I don't know where to put the xtrace? Tried without $ and it loops (no return outputed). Thanks again. – Sircutz – 2016-09-14T19:20:43.410

@Sircutz Place it right under the #!/bin/bash, I've edited my answer to reflect this. This only applies if you have a shell script (.sh) that you are executing. – Chip Shadd – 2016-09-15T14:49:21.173

I assumed the command needed to be scripted. I can handle that - make file , chmods for executable permission and run it. Can't wait to see what it says. Thanks again. – Sircutz – 2016-09-15T17:48:35.413

Built it and ran it. The xtrace output is fantastic but can not get "my shell script" to do what I wanted- navigate. Here is the script and then the output from bash. – Sircutz – 2016-09-15T18:32:07.900

#! /bin/bash set -o xtrace cd "$(cygpath -u 'C:\Documents and Settings\Administrator\My Documents\Downloads')" ; – Sircutz – 2016-09-15T18:32:18.017

doug0@indiv-insp1520 ~ $ ./cd.sh ++ cygpath -u 'C:\Documents and Settings\Administrator\My Documents\Downloads'

  • cd '/cygdrive/c/Documents and Settings/Administrator/My Documents/Downloads' ''

Update- i think I am getting closer. The last output you see is after adding the line ending charachters >>>> ; <<<< backslash semicolon – Sircutz – 2016-09-15T18:34:06.490

Output is exactly what I need , just did not change directory in the shell, only worked on the path. I guess pipe the OUTPUT to new shell would do it? Sorry I am a big pain in the ass. – Sircutz – 2016-09-15T18:37:22.210