-1

1

then I find that

4

I have thought the former just put several strings as one and explain that one. But there is something wrong with it. I can't understand what happens.

Pratap Alok Raj
  • 1,098
  • 10
  • 19
  • please copy the text and paste here. [Do not upload images of code/errors when asking a question.](//meta.stackoverflow.com/q/285551) – phuclv Jun 16 '21 at 04:36
  • Does this answer your question? [How can I escape a double quote inside double quotes?](https://stackoverflow.com/questions/3834839/how-can-i-escape-a-double-quote-inside-double-quotes) – Ken Y-N Jun 16 '21 at 04:42
  • Unquoted tilde is treated specially by some shells. Compare `echo ~` and `echo "~"`. Now think about how `dirname` will operate on each value. – jhnc Jun 16 '21 at 04:50
  • the quotes outside the subshell also makes a difference due to word splitting behavior: [Why does this echo behavior differ between a quoted string and unquoted string?](https://stackoverflow.com/q/67996498/995714), [I just assigned a variable, but echo $variable shows something else](https://stackoverflow.com/q/29378566/995714) – phuclv Jun 16 '21 at 05:20

2 Answers2

0

When you put any special character or any command with its parameters inside "" (double quotes) then it treats it as a complete string and then will try to compute.

The below example will make it more clear: -

9

Below reference is taken from here (It's an awesome reference, please give it a try for understanding on how ubuntu treats ' and "):-

3.1.2.2 Single Quotes

Enclosing characters in single quotes (') preserve the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

3.1.2.3 Double Quotes

Enclosing characters in double-quotes (") preserves the literal value of all characters within the quotes, with the exception of $, <tick_mark>, , and, when history expansion is enabled, !. The characters $ and >retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: $, <tick_mark>, ", , or newline. Within do>uble >quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed.>

The special parameters * and @ have special meaning when in double quotes (see Shell Parameter Expansion).

What is wrong with your command

For command "$(dirname "~")":- Ubuntu will first treat $(dirname "~") as a complete string and will try to compute, then further breaking it down, ubuntu will try to execute command dirname "~" as ~ is inside a "", it is treated as a single string and because of the below explained stupid behavior of dirname it will return ., i.e the current working directory

Working of dirname: -

The dirname command a straightforward syntax -- dirname OPTION PATH

Using dirname command with the absolute path of a file will give the directory path:

dirname /home/user/data/filename.txt
/home/user/data

The dirname command is also stupid actually. It doesn’t really recognize the file path. It just looks for the slashes (/) and prints whatever is before the last slash. Basically, you can give it any string with/in it and it will work on it.

For example, I am using a random string here with no filename in it. You can see that it still works the same and outputs a string removing the last / and the text after it. 1

If the path has no slash (/) in it, it will output a dot (.) implying the current directory. 2

Pratap Alok Raj
  • 1,098
  • 10
  • 19
  • Thank you very much, and in this case `DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )` , is it right to remove all the double quotes? I have tried in a script and get the same output, but I am not sure if it's a standard writing. – Shadow Black Jun 16 '21 at 09:49
  • If you are writing a shell script, it';s not a standard way to assign a command to a variable under double quotes until and unless you explicitly need them – Pratap Alok Raj Jun 16 '21 at 11:04
  • Please accept and upvote if you feel that my answer resolves your issue :) – Pratap Alok Raj Jun 16 '21 at 11:05
0

Maybe you could using man command for the detail about dirname by execute man dirname.

NAME
   dirname - strip last component from file name

SYNOPSIS
   dirname [OPTION] NAME...

DESCRIPTION
   Output each NAME with its last non-slash component and trailing slashes removed; 
if NAME contains no /'s, output '.' (meaning the current directory).

   -z, --zero
          end each output line with NUL, not newline

   --help display this help and exit

   --version
          output version information and exit

EXAMPLES
   dirname /usr/bin/
          -> "/usr"

   dirname dir1/str dir2/str
          -> "dir1" followed by "dir2"

   dirname stdio.h
          -> "."
Victor Lee
  • 2,467
  • 3
  • 19
  • 37