¿Cómo funciona el uso de tilde como acceso directo a mi directorio personal?

30

Estaba confundido, tratando de copiar algunos archivos de una PC a otra. Lo tengo resuelto, pero la sintaxis sigue siendo confusa para mí. Esto funciona:

scp ~/Desktop/Volenteer.png jay@server.ip:~j0h/b

que pone Volenteer.pngen la carpeta /home/j0h/b. Sin embargo, esto no funciona:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Esto también falla, dando un estado de salida 1 archivo no encontrado:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

Como hace esto:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

Claramente, hay alguna diferencia entre ~y ~/ esa diferencia es la presencia de/

$~/
bash: /home/j0h/: Is a directory
$ ~
bash: /home/j0h: Is a directory

Entonces, ¿por qué en scp, la ~resolución lo hace ~/? Es una suposición, no puedo verificar que eso es lo que está sucediendo. Pero parece inconsistente y, por lo tanto, confuso. ¿Es esto un error en scp? o hay algo sobre tilde que me estoy perdiendo?

j0h
fuente
2
Solo una nota al margen aquí, se deletrea "voluntario", con una "u" en lugar de una "e" :)
AER
2
Soy un deletreador liberal.
j0h
Pregunta relacionada: askubuntu.com/q/972319/295286
Sergiy Kolodyazhnyy

Respuestas:

68

~ es tu directorio personal

~fooes el directorio de inicio del usuario foo, si dicho usuario existe, o simplemente un directorio llamado ~foo, si ese usuario no existe.


Por lo tanto, en:

scp ~Desktop/Volenteer.png     jay@server.ip:~j0h/b

~Desktopse expandirá al directorio de inicio del usuario Desktop, si dicho usuario existe (y generalmente no existe), o será solo ~Desktop(una ruta que generalmente tampoco existe).


En:

scp ~/Desktop/Volenteer.png     jay@server.ip:~/j0h/b

~/j0hse expandirá a un directorio nombrado j0hen jayel directorio de inicio de '', que, nuevamente, es poco probable que exista.


No es ~y ~/dónde ocurre la diferencia, sino en ~y ~foo.


Además, ~también se puede utilizar para la navegación del historial del directorio:

  • ~-es el directorio de trabajo anterior (como $OLDPWD)
  • ~+es el directorio de trabajo actual (como $PWD)

Esto no es aplicable scp, ya que no puede cambiar los directorios en medio de una scpoperación.

Y si se utiliza pushdypopd para mantener una pila de directorios, y sería el directorio º en la pila de directorios, como se ve en la salida . sería el th directorio desde el final (contando desde cero, en ambos casos). Por ejemplo:~N~+NNdirs~-NN

$ for i in etc usr var tmp; do pushd /$i; done
/etc ~/.vim
/usr /etc ~/.vim
/var /usr /etc ~/.vim
/tmp /var /usr /etc ~/.vim

$ dirs
/tmp /var /usr /etc ~/.vim

Luego, se puede acceder a los directorios en la pila usando:

/tmp /var /usr /etc ~/.vim
  ~0   ~1   ~2   ~3     ~4
 ~+0  ~+1  ~+2  ~+3    ~+4
 ~-4  ~-3  ~-2  ~-1    ~-0 
  ~+   ~-
muru
fuente
Entonces, ~+siempre es equivalente a .entonces, ¿es eso correcto? Parece redundante
Comodín el
1
@Wildcard bien, no exactamente. ~+y ~-use los valores de $PWDy $OLDPWD, que son rutas absolutas. .Siempre es un camino relativo. Entonces, si hay un comando que cambia el directorio de trabajo actual cuando se ejecuta, verá la nueva ruta para ., donde la ruta expandida ~-seguirá siendo la misma. tar -Ces un ejemplo, aunque admito que no puedo pensar en un buen uso para ~+. $PWDsería igual de bueno, excepto que no necesita comillas ~+/foo/barsi $PWDcontiene espacios.
muru
1
Gracias, eso lo aclara. En realidad, ese es un buen ejemplo de caso de uso: algunos comandos se niegan a operar en rutas relativas por razones de seguridad; con tales comandos que no puedes usar ./filenamepero puedes usar "$PWD/filename"o más simplemente ~+/filename. (Y algunos comandos funcionarán en nombres de ruta relativos, pero hay una diferencia funcional, como lno tar.)
Comodín el
21

Lea la documentación de GNU para Bash Tilde Expansion (como debería haberlo hecho antes de mi primera iteración de esta respuesta).

~/Desktopy ~j0hestán haciendo cosas fundamentalmente diferentes, lo que explica por qué ~Desktopno funciona:

  • Se ~sustituye un plano por su $HOMEvariable de entorno actual , establecida al iniciar sesión. Así lo ~resuelve /home/olipara mí, y se ~/Desktoplee como /home/oli/Desktop. Aquí es donde ves que se usa más la tilda.

  • ~usernamese resuelve en el hogar de ese usuario , como se establece en /etc/passwd. Así que ~oliresuelve /home/oli, ~j0hpodría resolverse /home/j0hpero no necesariamente, su homedir puede estar en cualquier lugar.

  • ~not-a-usernameno se resuelve Porque Desktopno es un usuario, ~Desktopno está sustituido. Se toma literalmente como un archivo o ruta llamada ~Desktop(que no existe aquí).

Y no hace falta decir que todo esto ocurre de forma remota (sería inútil scpsi se reemplazara con valores locales). Esto funciona porque Bash no sustituirá ~...si está precedido por otra cosa que no sea un espacio en blanco.

Oli
fuente
Que getent passwd bindice
muru
2
"bin" es un usuario del sistema en la mayoría de las máquinas Linux, con un directorio de inicio de / bin.
fNek
1
La falla de expansión ~dires consistente con los documentos de GNU: "... los caracteres en el prefijo tilde que siguen a la tilde se tratan como un posible nombre de inicio de sesión ... Si el nombre de inicio de sesión no es válido o la expansión de tilde falla, la palabra no se modifica ". Aquí, dirno es el nombre de un usuario en este sistema, por lo que no se modifica.
apsillers
Gracias a todos. Probablemente debería leer los enlaces que publico :)
Oli
4

El símbolo ~se usa como acceso directo para /home/userin bash, por lo que en el caso de ~/Desktop/Volenteer.pngque sea abreviado para /home/user/Desktop/Volenteer.png.

Como puede ver /, como siempre, muestra un nuevo nivel en la jerarquía del sistema de archivos.

Mark Kirby
fuente
3
solo a la mitad, es una abreviatura de la variable de entorno $ HOME. ~{user}/podría ser cualquier ruta aleatoria establecida por el archivo de base de datos passwd (5). Si bien sí, los estándares filesytem.org ubican a los usuarios regulares en / home, este no es el caso con todos los usuarios (es decir, root in / root y servicios en / var / ... o unixies anteriores que usan / usr en lugar de / home)
Dwight Spencer
DwightSpencer es correcto. Mantengo varios servidores donde los usuarios están en / usr / {CLIENTNAME} / home / y se comparten en varios sistemas internos y remotos (todos apuntan a ese directorio), por lo que solo se necesita mantener 1 sistema. Y ~ apunta a ese directorio;)
Rinzwind
3
@Rinzwind eek. Debo protestar por este mal uso sacrílego /usr.
muru
@muru oye, no era MI llamada>: - D Fue un sobrante de SCO D:
Rinzwind
1
Sinceramente, me gustó el uso de / usr para todo lo relacionado con el usuario, ya que eso era lo que originalmente significaba. Lo que encuentro en estos días es el mal uso más sacrílego de / usr / bin como un gran vertedero unificado de todos los binarios (sys, user, sysop) fuera de los binutils base. Después de todo / usr se entiende como todas las cosas a las que los usuarios tienen acceso desde un montaje nfs, mientras que / usr / local era el espacio de usuario local con / sbin como binarios de sysop y binarios del sistema / bin. Entiendo que / home puede ser una partición diferente, pero también puede / usr / home / ... mantenerlo en / usr lo mantiene como espacio de nombre de usuario tanto en política, implementación y mentalidad.
Dwight Spencer
3

~es la abreviatura de la variable de entorno $HOMEen la mayoría de los shells compatibles con derivados de c shell / POSIX compatibles. El uso más común ~es cuando se hace referencia a su propio directorio personal o al de la casa de otro usuario:

cd ~ # ie shell, take me to my home folder

cd ~root # i.e. shell, take me to root's home folder

Para encontrar el directorio de inicio de cualquier usuario local en un sistema POSIX (UNIX, Linux, OS X, BSD) que está utilizando la base de datos passwd (5) , ejecute awk de esta /etc/passwdmanera:

awk -F: '{ print $1,$(NF-1) }' /etc/passwd

Esto mostrará una lista de cada usuario local y su directorio de inicio.

Dwight Spencer
fuente