Как найти путь до файла bash

Use realpath

$ realpath example.txt
/home/username/example.txt

Boris Verkhovskiy's user avatar

answered Oct 12, 2010 at 13:16

Benjamin Bannier's user avatar

Benjamin BannierBenjamin Bannier

54.4k11 gold badges60 silver badges80 bronze badges

22

Try readlink which will resolve symbolic links:

readlink -e /foo/bar/baz

answered Oct 12, 2010 at 14:34

Dennis Williamson's user avatar

Dennis WilliamsonDennis Williamson

343k90 gold badges373 silver badges438 bronze badges

13

#! /bin/sh
echo "$(cd "$(dirname -- "$1")" >/dev/null; pwd -P)/$(basename -- "$1")"

doekman's user avatar

doekman

18.6k20 gold badges64 silver badges86 bronze badges

answered Oct 12, 2010 at 13:51

dogbane's user avatar

dogbanedogbane

265k75 gold badges395 silver badges413 bronze badges

14

Forget about readlink and realpath which may or may not be installed on your system.

Expanding on dogbane’s answer above here it is expressed as a function:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

you can then use it like this:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

How and why does it work?

The solution exploits the fact that the Bash built-in pwd command will print the absolute path of the current directory when invoked without arguments.

Why do I like this solution ?

It is portable and doesn’t require neither readlink or realpath which often does not exist on a default install of a given Linux/Unix distro.

What if dir doesn’t exist?

As given above the function will fail and print on stderr if the directory path given does not exist. This may not be what you want. You can expand the function to handle that situation:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  if [ -d "$(dirname "$1")" ]; then
    echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
  fi
}

Now it will return an empty string if one the parent dirs do not exist.

How do you handle trailing ‘..’ or ‘.’ in input ?

Well, it does give an absolute path in that case, but not a minimal one. It will look like:

/Users/bob/Documents/..

If you want to resolve the ‘..’ you will need to make the script like:

get_abs_filename() {
  # $1 : relative filename
  filename=$1
  parentdir=$(dirname "${filename}")

  if [ -d "${filename}" ]; then
      echo "$(cd "${filename}" && pwd)"
  elif [ -d "${parentdir}" ]; then
    echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
  fi
}

answered Jan 17, 2014 at 14:24

peterh's user avatar

peterhpeterh

18.1k11 gold badges84 silver badges114 bronze badges

14

$ readlink -m FILE
/path/to/FILE

This is better than readlink -e FILE or realpath, because it works even if the file doesn’t exist.

answered Feb 27, 2013 at 17:04

Flimm's user avatar

FlimmFlimm

133k45 gold badges249 silver badges260 bronze badges

5

This relative path to absolute path converter shell function

  • requires no utilities (just cd and pwd)
  • works for directories and files
  • handles .. and .
  • handles spaces in dir or filenames
  • requires that file or directory exists
  • returns nothing if nothing exists at the given path
  • handles absolute paths as input (passes them through essentially)

Code:

function abspath() {
    # generate absolute path from relative path
    # $1     : relative filename
    # return : absolute path
    if [ -d "$1" ]; then
        # dir
        (cd "$1"; pwd)
    elif [ -f "$1" ]; then
        # file
        if [[ $1 = /* ]]; then
            echo "$1"
        elif [[ $1 == */* ]]; then
            echo "$(cd "${1%/*}"; pwd)/${1##*/}"
        else
            echo "$(pwd)/$1"
        fi
    fi
}

Sample:

# assume inside /parent/cur
abspath file.txt        => /parent/cur/file.txt
abspath .               => /parent/cur
abspath ..              => /parent
abspath ../dir/file.txt => /parent/dir/file.txt
abspath ../dir/../dir   => /parent/dir          # anything cd can handle
abspath doesnotexist    =>                      # empty result if file/dir does not exist
abspath /file.txt       => /file.txt            # handle absolute path input

Note: This is based on the answers from nolan6000 and bsingh, but fixes the file case.

I also understand that the original question was about an existing command line utility. But since this seems to be THE question on stackoverflow for that including shell scripts that want to have minimal dependencies, I put this script solution here, so I can find it later :)

answered Apr 11, 2014 at 2:12

Alexander Klimetschek's user avatar

11

The find command may help

find $PWD -name ex*
find $PWD -name example.log

Lists all the files in or below the current directory with names matching the pattern. You can simplify it if you will only get a few results (e.g. directory near bottom of tree containing few files), just

find $PWD

I use this on Solaris 10, which doesn’t have the other utilities mentioned.

Matteo Italia's user avatar

Matteo Italia

123k17 gold badges205 silver badges298 bronze badges

answered Oct 12, 2011 at 16:26

lessthanideal's user avatar

6

Here’s a zsh-only function that I like for its compactness. It uses the ‘A’ expansion modifier — see zshexpn(1).

realpath() { for f in "$@"; do echo ${f}(:A); done }

answered Sep 24, 2012 at 13:59

wjv's user avatar

wjvwjv

2,2481 gold badge17 silver badges21 bronze badges

1

If you don’t have readlink or realpath utilities than you can use following function which works in bash and zsh (not sure about the rest).

abspath () { case "$1" in /*)printf "%sn" "$1";; *)printf "%sn" "$PWD/$1";; esac; }

This also works for nonexistent files (as does the python function os.path.abspath).

Unfortunately abspath ./../somefile doesn’t get rid of the dots.

answered Oct 12, 2010 at 14:59

hluk's user avatar

hlukhluk

5,7782 gold badges21 silver badges19 bronze badges

5

There is generally no such thing as the absolute path to a file (this statement means that there may be more than one in general, hence the use of the definite article the is not appropriate). An absolute path is any path that start from the root «/» and designates a file without ambiguity independently of the working directory.(see for example wikipedia).

A relative path is a path that is to be interpreted starting from another directory. It may be the working directory if it is a relative path being manipulated by an application
(though not necessarily). When it is in a symbolic link in a directory, it is generally intended to be relative to that directory (though the user may have other uses in mind).

Hence an absolute path is just a path relative to the root directory.

A path (absolute or relative) may or may not contain symbolic links. If it does not, it is also somewhat impervious to changes in the linking structure, but this is not necessarily required or even desirable. Some people call canonical path ( or canonical file name or resolved path) an absolute path in which all symbolic links have been resolved, i.e. have been replaced by a path to whetever they link to. The commands realpath and readlink both look for a canonical path, but only realpath has an option for getting an absolute path without bothering to resolve symbolic links (along with several other options to get various kind of paths, absolute or relative to some directory).

This calls for several remarks:

  1. symbolic links can only be resolved if whatever they are supposed to
    link to is already created, which is obviously not always the case. The commands realpath and readlink have options to account for that.
  2. a directory on a path can later become a symbolic link, which means that the path is no longer canonical. Hence the concept is time (or environment) dependent.
  3. even in the ideal case, when all symbolic links can be resolved,
    there may still be more than one canonical path to a file, for two
    reasons:

    • the partition containing the file may have been mounted simultaneously (ro) on several mount points.
    • there may be hard links to the file, meaning essentially the the file exists in several different directories.

Hence, even with the much more restrictive definition of canonical path, there may be several canonical paths to a file. This also means that the qualifier canonical is somewhat inadequate since it usually implies a notion of uniqueness.

This expands a brief discussion of the topic in an answer to another similar question at Bash: retrieve absolute path given relative

My conclusion is that realpath is better designed and much more flexible than readlink.
The only use of readlink that is not covered by realpath is the call without option returning the value of a symbolic link.

Community's user avatar

answered May 19, 2013 at 17:40

babou's user avatar

baboubabou

6328 silver badges10 bronze badges

15

The simplest if you want to use only builtins is probably:

find `pwd` -name fileName

Only an extra two words to type, and this will work on all unix systems, as well as OSX.

answered Oct 24, 2019 at 10:54

Arj's user avatar

ArjArj

1,9414 gold badges25 silver badges45 bronze badges

4

The dogbane answer with the description what is coming on:

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

Explanation:

  1. This script get relative path as argument "$1"
  2. Then we get dirname part of that path (you can pass either dir or file to this script): dirname "$1"
  3. Then we cd "$(dirname "$1") into this relative dir and get absolute path for it by running pwd shell command
  4. After that we append basename to absolute path: $(basename "$1")
  5. As final step we echo it

Community's user avatar

answered May 20, 2017 at 10:03

Eugen Konkov's user avatar

Eugen KonkovEugen Konkov

21.6k14 gold badges104 silver badges150 bronze badges

The top answers in this question may be misleading in some cases. Imagine that the file, whose absolute path you want to find, is in the $PATH variable:

# node is in $PATH variable
type -P node
# /home/user/.asdf/shims/node
cd /tmp
touch node  # But because there is a file with the same name inside the current dir check out what happens below
readlink -e node
# /tmp/node
readlink -m node
# /tmp/node
readlink -f node
# /tmp/node
echo "$(cd "$(dirname "node")"; pwd -P)/$(basename "node")"
# /tmp/node
realpath node
# /tmp/node
realpath -e node
# /tmp/node

# Now let's say that for some reason node does not exist in current directory
rm node
readlink -e node
# <nothing printed>
readlink -m node    
# /tmp/node         # Note: /tmp/node does not exist, but is printed
readlink -f node
# /tmp/node         # Note: /tmp/node does not exist, but is printed
echo "$(cd "$(dirname "node")"; pwd -P)/$(basename "node")"
# /tmp/node         # Note: /tmp/node does not exist, but is printed
realpath node
# /tmp/node         # Note: /tmp/node does not exist, but is printed
realpath -e node
# realpath: node: No such file or directory

Based on the above I can conclude that: realpath -e and readlink -e can be used for finding the absolute path of a file, that we expect to exist in current directory, without result being affected by the $PATH variable. The only difference is that realpath outputs to stderr, but both will return error code if file is not found:

cd /tmp
rm node
realpath -e node ; echo $?
# realpath: node: No such file or directory
# 1
readlink -e node ; echo $?
# 1

Now in case you want the absolute path a of a file that exists in $PATH, the following command would be suitable, independently on whether a file with same name exists in current dir.

type -P example.txt
# /path/to/example.txt

# Or if you want to follow links
readlink -e $(type -P example.txt)
# /originalpath/to/example.txt

# If the file you are looking for is an executable (and wrap again through `readlink -e` for following links )
which executablefile
# /opt/bin/executablefile

And a, fallback to $PATH if missing, example:

cd /tmp
touch node
echo $(readlink -e node || type -P node)
# /tmp/node
rm node
echo $(readlink -e node || type -P node)
# /home/user/.asdf/shims/node

answered Feb 4, 2021 at 10:43

Marinos An's user avatar

Marinos AnMarinos An

9,1316 gold badges59 silver badges94 bronze badges

Answer with Homebrew

realpath is the best answer, but if you don’t have it installed, you must first run brew install coreutils which will install coreutils with lots of awesome functions. Writing a custom function and exporting it is too much work and risk for error for something like this, here are two lines:

$ brew install coreutils
$ realpath your-file-name.json 

answered Jun 1, 2020 at 19:02

Zorayr's user avatar

ZorayrZorayr

23.5k7 gold badges135 silver badges126 bronze badges

2

For directories dirname gets tripped for ../ and returns ./.

nolan6000’s function can be modified to fix that:

get_abs_filename() {
  # $1 : relative filename
  if [ -d "${1%/*}" ]; then
    echo "$(cd ${1%/*}; pwd)/${1##*/}"
  fi
}

Community's user avatar

answered Mar 21, 2014 at 7:13

bsingh's user avatar

4

This is not an answer to the question, but for those who does scripting:

echo `cd "$1" 2>/dev/null&&pwd||(cd "$(dirname "$1")";pwd|sed "s|/*$|/${1##*/}|")`

it handles / .. ./ etc correctly. I also seems to work on OSX

answered Mar 16, 2016 at 18:57

Alek's user avatar

AlekAlek

6067 silver badges7 bronze badges

I have placed the following script on my system & I call it as a bash alias for when I want to quickly grab the full path to a file in the current dir:

#!/bin/bash
/usr/bin/find "$PWD" -maxdepth 1 -mindepth 1 -name "$1"

I am not sure why, but, on OS X when called by a script «$PWD» expands to the absolute path. When the find command is called on the command line, it doesn’t. But it does what I want… enjoy.

answered Aug 21, 2016 at 5:50

fred.johnsen's user avatar

1

#! /bin/bash

file="$@"
realpath "$file" 2>/dev/null || eval realpath $(echo $file | sed 's/ /\ /g')

This makes up for the shortcomings of realpath, store it in a shell script fullpath. You can now call:

$ cd && touch a a && rm A 2>/dev/null 
$ fullpath "a a"
/home/user/a a
$ fullpath ~/a a
/home/user/a a
$ fullpath A
A: No such file or directory.

answered Apr 19, 2014 at 2:38

ShellFish's user avatar

ShellFishShellFish

4,3411 gold badge20 silver badges33 bronze badges

2

An alternative to get the absolute path in Ruby:

realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}

Works with no arguments (current folder) and relative and absolute file or folder path as agument.

answered Jan 10, 2017 at 16:16

Atika's user avatar

AtikaAtika

1,54018 silver badges18 bronze badges

The answer of Alexander Klimetschek is okay if your script may insist on a bash or bash compatible shell being present. It won’t work with a shell that is only POSIX conforming.

Also when the final file is a file in root, the output will be //file, which is not technically incorrect (double / are treated like single ones by the system) but it looks strange.

Here’s a version that works with every POSIX conforming shell, all external tools it is using are also required by the POSIX standard, and it explicitly handles the root-file case:

#!/bin/sh

abspath ( ) {
    if [ ! -e "$1" ]; then
        return 1
    fi

    file=""
    dir="$1"
    if [ ! -d "$dir" ]; then
        file=$(basename "$dir")
        dir=$(dirname "$dir")
    fi

    case "$dir" in
        /*) ;;
        *) dir="$(pwd)/$dir"
    esac
    result=$(cd "$dir" && pwd)

    if [ -n "$file" ]; then
        case "$result" in
            */) ;;
             *) result="$result/"
        esac
        result="$result$file"
    fi

    printf "%sn" "$result"
}

abspath "$1"

Put that into a file and make it executable and you have a CLI tool to quickly get the absolute path of files and directories. Or just copy the function and use it in your own POSIX conforming scripts. It turns relative paths into absolute ones and returns absolute ones as is.

Interesting modifications:

If you replace the line result=$(cd "$dir" && pwd) with result=$(cd "$dir" && pwd -P), then all symbolic links in the path to the final file are resolved as well.

If you are not interested into the first modification, you can optimize the absolute case by returning early:

abspath ( ) {
    if [ ! -e "$1" ]; then
        return 1
    fi

    case "$1" in
        /*)
            printf "%sn" "$1"
            return 0
    esac

    file=""
    dir="$1"
    if [ ! -d "$dir" ]; then
        file=$(basename "$dir")
        dir=$(dirname "$dir")
    fi

    result=$(cd "$dir" && pwd)

    if [ -n "$file" ]; then
        case "$result" in
            */) ;;
            *) result="$result/"
        esac
        result="$result$file"
    fi

    printf "%sn" "$result"
}

And since the question will arise: Why printf instead of echo?

echo is intended primary to print messages for the user to stdout. A lot of echo behavior that script writers rely on is in fact unspecified. Not even the famous -n is standardized or the usage of t for tab. The POSIX standard says:

A string to be written to standard output. If the first operand is -n, or if any of the operands contain a character, the results are implementation-defined.
— https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html

Thus whenever you want to write something to stdout and it’s not for the purpose of printing a message to the user, the recommendation is to use printf as the behavior of printf is exactly defined. My function uses stdout to pass out a result, this is not a message for the user and thus only using printf guarantees perfect portability.

answered Sep 6, 2020 at 11:49

Mecki's user avatar

MeckiMecki

124k32 gold badges241 silver badges251 bronze badges

I use the single line

(cd ${FILENAME%/*}; pwd)

However, this can only be used when $FILENAME has a leading path of any kind (relative or absolute) that actually exists. If there is no leading path at all, then the answer is simply $PWD. If the leading path does not exist, then the answer may be indeterminate, otherwise and the answer is simply ${FILENAME%/*} if the path is absolute.

Putting this all together I would suggest using the following function

function abspath() {
  # argument 1: file pathname (relative or absolute)
  # returns: file pathname (absolute)
  if [ "$1" == "${1##*/}" ]; then # no path at all
    echo "$PWD"
  elif [ "${1:0:1}" == "/" -a "${1/../}" == "$1" ]; then # strictly absolute path
    echo "${1%/*}"
  else # relative path (may fail if a needed folder is non-existent)
    echo "$(cd ${1%/*}; pwd)"
  fi
}

Note also that this only work in bash and compatible shells. I don’t believe the substitutions work in the simple shell sh.

answered Dec 31, 2020 at 15:05

David P. Chassin's user avatar

Hey guys I know it’s an old thread but I am just posting this for reference to anybody else who visited this like me. If i understood the question correctly, I think the locate $filename command. It displays the absolute path of the file supplied, but only if it exists.

answered Dec 5, 2014 at 12:01

icyyd's user avatar

icyydicyyd

12 bronze badges

1

Вы можете получить полный путь к текущему каталогу с помощью команды pwd:

pwd

Содержание

  1. Но как получить абсолютный путь к файлу в системах Linux?
  2. Использование команды readlink для получения пути к файлу
  3. Использование команды для получения полного пути к файлу
  4. Используем команду find для получения абсолютного пути к файлу
  5. Выведем полный путь с помощью команды ls
  6. Заключение

Но как получить абсолютный путь к файлу в системах Linux?

Существует несколько способов вывести полный путь к файлам:

  • readlink
  • realpath
  • найти
  • комбинирование ls и pwd

Позвольте мне показать вам эти команды по очереди.

Но перед этим я предлагаю сначала ознакомиться с основами концепции абсолютного и относительного пути.

  • 🐧 Как выполнить поиск Grep по всем файлам и во всех каталогах

Использование команды readlink для получения пути к файлу

Команда readlink предназначена для разрешения символических ссылок.

Вы можете использовать ее для отображения полного пути к файлу следующим образом:

readlink -f filename

Вот пример:

readlink -f sample.txt

/home/itsecforu/sample.txt

Использование команды для получения полного пути к файлу

Команда realpath используется для разрешения абсолютных имен файлов.

Помимо прочего, она может показать полный путь к файлу.

realpath filename

Взгляните на этот пример:

realpath sample.txt

/home/itsecforu/sample.txt

Если вы используете файл с символической ссылкой, он покажет реальный путь к исходному файлу.

Вы можете заставить его не следовать за символической ссылкой:

realpath -s filename

Вот пример, где он по умолчанию показывает полный путь к исходному файлу, а затем я заставил его показать символическую ссылку, а не исходный файл.

realpath linking-park

/home/itsecforu/Documents/ubuntu-commands.md

realpath -s linking-park

Используем команду find для получения абсолютного пути к файлу

Вот в чем дело с командой find.

Все относительно каталога, который вы указываете для поиска.

Если вы укажете ей ., она покажет относительный путь.

Если вы укажете абсолютный путь к каталогу, вы получите абсолютный путь к искомым файлам.

Используйте подстановку команд с командой find следующим образом:

find $(pwd) -name filename

Вы можете запустить команду для поиска полного пути к одному файлу:

find $(pwd) -name sample.txt

/home/itsecforu/sample.txt

Или вы можете использовать его с кучей файлов, соответствующих определенному шаблону:

find $(pwd) -name "*.pdf"

/home/itsecforu/Documents/eBooks/think-like-a-programmer.pdf

/home/itsecforu/Documents/eBooks/linux-guide.pdf

/home/itsecforu/Documents/eBooks/absolute-open-bsd.pdf

/home/itsecforu/Documents/eBooks/theory-of-fun-for-game-design.pdf

/home/itsecforu/Documents/eBooks/Ubuntu 1804 english.pdf

/home/itsecforu/Documents/eBooks/computer_science_distilled_v1.4.pdf

/home/itsecforu/Documents/eBooks/the-art-of-debugging-with-gdb-and-eclipse.pdf

Выведем полный путь с помощью команды ls

Этот способ немного сложный и запутанный.

Вы можете использовать переменную окружения PWD с командой ls следующим образом, чтобы отобразить файлы и каталоги с их абсолютным путем:

ls -ld $PWD/*

Вы получите результат, подобный этому:

ls -ld $PWD/*

-r--rw-r-- 1 itsecforu itsecforu 0 Jul 27 16:57 /home/itsecforu/test/file2.txt

drwxrwxr-x 2 itsecforu itsecforu 4096 Aug 22 16:58 /home/itsecforu/test/new

Однако, чтобы вывести полный путь к файлу с помощью команды ls, вам придется использовать ее следующим образом:

ls -l $PWD/filename

Не самое чистое решение, но оно работает.

$ ls -l $PWD/sample.txt 
-rw-r--r-- 1 itsecforu itsecforu 12813 Sep  7 11:50 /home/itsecforu/sample.txt

Заключение

Мы рассмотрели четыре различных способа получения полного пути к файлу в Linux.

Команды find и ls являются обычными, в то время как realpath и readlink едва ли известны многим пользователям Linux.

Всегда полезно узнавать что-то новое, не так ли?

см. также:

  • 🐧 Как улучшить время загрузки apt
  • 📦 Как проверить, был ли какой-либо из файлов RPM добавлен или изменен
  • 📂 Как найти текущий рабочий каталог процесса, используя Pwdx на Linux
  • 🏪 Linux для пентестера: использование Find для повышение привилегий
  • 🔳 findmnt – показывает установленные в настоящее время файловые системы в Linux
  • Findsploit – найти эксплойты локальных и онлайн баз данных
  • 🐧 Поиск файлов, измененных за последние N минут на Linux
  • 🔎 Аудит исходного кода с помощью GREP

Время на прочтение
5 мин

Количество просмотров 125K

Иногда критически важно быстро найти нужный файл или информацию в системе. Порой можно ограничиться стандартами функциями поиска, которыми сейчас обладает любой файловый менеджер, но с возможностями терминала им не сравниться.

Команда find – это невероятно мощный инструмент, позволяющий искать файлы не только по названию, но и по:

  • Дате добавления.
  • Содержимому.
  • Регулярным выражениям.

Данная команда будет очень полезна системным администраторам для:

  • Управления дисковым пространством.
  • Бэкапа.
  • Различных операций с файлами.

Команда find в Linux производит поиск файлов и папок на основе заданных вами критериев и позволяет выполнять действия с результатами поиска.

Синтаксис команды find:

$ find directory-to-search criteria action

Где:

  • directory-to-search (каталог поиска) – это отправной каталог, с которой find начинает поиск файлов по всем подкаталогам, которые находятся внутри. Если не указать путь, тогда поиск начнется в текущем каталоге;
  • criteria (критерий) – критерий, по которым нужно искать файлы;
  • action (действие) – что делать с каждым найденным файлом, соответствующим критериям.

Поиск по имени

Следующая команда ищет файл s.txt в текущем каталоге:

$ find . -name "s.txt"
./s.txt

Где:

  • . (точка) – файл относится к нынешнему каталогу
  • -name – критерии по которым осуществляется поиск. В данном случае поиск по названию файла.

В данном случае критерий -name учитывает только символы нижнего регистра и файл S.txt не появиться в результатах поиска. Чтобы убрать чувствительность к регистру необходимо использовать –iname.

$ find . -iname "s.txt"
./s.txt
./S.txt

Для поиска всех изображений c расширением .png нужно использовать шаблон подстановки *.png:

$ find . -name "*.png"
./babutafb.png
./babutafacebook.png
./Moodle2.png
./moodle.png
./moodle/moodle1.png
./genxfacebook.png

Можно использовать название каталога для поиска. Например, чтобы с помощью команды find найти все png изображения в каталоге home:

$ find /home -name "*.png"
find: `/home/babuta/.ssh': Permission denied
/home/vagrant/Moodle2.png
/home/vagrant/moodle.png
/home/tisha/hello.png
find: `/home/tisha/testfiles': Permission denied
find: `/home/tisha/data': Permission denied
/home/tisha/water.png
find: `/home/tisha/.cache': Permission denied

Если выдает слишком много ошибок в отказе разрешения, тогда можно добавить в конец команды – 2> /dev/null. Таким образом сообщения об ошибках будут перенаправляться по пути dev/null, что обеспечит более чистую выдачу.

find /home -name "*.jpg" 2>/dev/null
/home/vagrant/Moodle2.jpg
/home/vagrant/moodle.jpg
/home/tisha/hello.jpg
/home/tisha/water.jpg

Поиск по типу файла

Критерий -type позволяет искать файлы по типу, которые бывают следующих видов:

  • f – простые файлы;
  • d – каталоги;
  • l – символические ссылки;
  • b – блочные устройства (dev);
  • c – символьные устройства (dev);
  • p – именованные каналы;
  • s – сокеты;

Например, указав критерий -type d будут перечислены только каталоги:

$ find . -type d
.
./.ssh
./.cache
./moodle

Поиск по размеру файла

Допустим, что вам необходимо найти все большие файлы. Для таких ситуаций подойдет критерий -size.

  • «+» — Поиск файлов больше заданного размера
  • «-» — Поиск файлов меньше заданного размера
  • Отсутствие знака означает, что размер файлов в поиске должен полностью совпадать.

В данном случае поиск выведет все файлы более 1 Гб (+1G).

$ find . -size +1G
./Microsoft_Office_16.29.19090802_Installer.pkg
./android-studio-ide-183.5692245-mac.dmg

Единицы измерения файлов:

  • c — Байт
  • k — Кбайт
  • M — Мбайт
  • G — Гбайт

Поиск пустых файлов и каталогов

Критерий -empty позволяет найти пустые файлы и каталоги.

$ find . -empty
./.cloud-locale-test.skip
./datafiles
./b.txt
...
./.cache/motd.legal-displayed

Поиск времени изменения

Критерий -cmin позволяет искать файлы и каталоги по времени изменения. Для поиска всех файлов, измененных за последний час (менее 60 мин), нужно использовать -60:

$ find . -cmin -60
.
./a.txt
./datafiles

Таким образом можно найти все файлы в текущем каталоге, которые были созданы или изменены в течение часа (менее 60 минут).

Для поиска файлов, которые наоборот были изменены в любое время кроме последнего часа необходимо использовать +60.

$ find . -cmin +60

Поиск по времени доступа

Критерий -atime позволяет искать файлы по времени последнего доступа.

$ find . -atime +180

Таким образом можно найти файлы, к которым не обращались последние полгода (180 дней).

Поиск по имени пользователя

Опция –user username дает возможность поиска всех файлов и каталогов, принадлежащих конкретному пользователю:

$ find /home -user tisha 2>/dev/null

Таким образом можно найти все файлы пользователя tisha в каталоге home, а 2>/dev/null сделает выдачу чистой без ошибок в отказе доступа.

Поиск по набору разрешений

Критерий -perm – ищет файлы по определенному набору разрешений.

$ find /home -perm 777

Поиск файлов с разрешениями 777.

Операторы

Для объединения нескольких критериев в одну команду поиска можно применять операторы:

  • -and
  • -or
  • -not

Например, чтобы найти файлы размером более 1 Гбайта пользователя tisha необходимо ввести следующую команду:

$ find /home  -user tisha  -and  -size +1G  2>/dev/null

Если файлы могут принадлежать не только пользователю tisha, но и пользователю pokeristo, а также быть размером более 1 Гбайта.

$ find /home ( -user pokeristo -or -user tisha )  -and  -size +1G  2>/dev/null

Перед скобками нужно поставить обратный слеш «».

Действия

К команде find можно добавить действия, которые будут произведены с результатами поиска.

  • -delete — Удаляет соответствующие результатам поиска файлы
  • -ls — Вывод более подробных результатов поиска с:
    • Размерами файлов.
    • Количеством inode.
  • -print Стоит по умолчанию, если не указать другое действие. Показывает полный путь к найденным файлам.
  • -exec Выполняет указанную команду в каждой строке результатов поиска.

-delete

Полезен, когда необходимо найти и удалить все пустые файлы, например:

$ find . -empty -delete

Перед удалением лучше лишний раз себя подстраховать. Для этого можно запустить команду с действием по умолчанию -print.

-exec:

Данное действие является особенным и позволяет выполнить команду по вашему усмотрению в результатах поиска.

-exec command {} ;

Где:

  • command – это команда, которую вы желаете выполнить для результатов поиска. Например:
    • rm
    • mv
    • cp
  • {} – является результатами поиска.
  • ; — Команда заканчивается точкой с запятой после обратного слеша.

С помощью –exec можно написать альтернативу команде –delete и применить ее к результатам поиска:

$ find . -empty -exec rm {} ;

Другой пример использования действия -exec:

$ find . -name "*.jpg" -exec cp {} /backups/fotos ;

Таким образом можно скопировать все .jpg изображения в каталог backups/fotos

Заключение

Команду find можно использовать для поиска:

  • Файлов по имени.
  • Дате последнего доступа.
  • Дате последнего изменения.
  • Имени пользователя (владельца файла).
  • Имени группы.
  • Размеру.
  • Разрешению.
  • Другим критериям.

С полученными результатами можно сразу выполнять различные действия, такие как:

  • Удаление.
  • Копирование.
  • Перемещение в другой каталог.

Команда find может сильно облегчить жизнь системному администратору, а лучший способ овладеть ей – больше практиковаться.

image

В этом разделе вы познакомитесь с основами навигации по системе. Для множества задач нужно уметь добираться до конкретного места в системе, и эти навыки формируют фундамент вашего успеха в работе с Linux. Постарайтесь разобраться в навигации.

Как узнать, в какой директории вы находитесь

Первая команда, которую мы изучим — pwd, сокращение от Print Working Directory (выведи рабочую директорию). Вы скоро увидите, что множество команд в Linux — это аббревиатуры слов, описывающих их. Это помогает лучше их запомнить. Собственно, команда и выводит текущую рабочую директорию. Попробуйте использовать ее.

1. pwd
2. /home/karpaff

Правильное выполнение многих команд терминала зависит от того, в нужном ли месте вы находитесь. Почаще используйте эту команду, чтобы не забывать, в какой вы директории.

Как узнать содержимое директории

Мы научились определять, в какой директории мы находимся. Теперь давайте научимся узнавать содержимое директории. В этом нам поможет команда ls — сокращение от list (список). Давайте опробуем ее.

1. ls
2. bin Documents public_html

Команда pwd отрабатывает сама по себе, без аргументов. ls в этом плане посильнее. В случае выше мы запустили ее без аргументов — она выведет список содержимого данной директории. Но от ls можно получить больше — ниже дана схема ее использования:

ls [ключи] [директория]

В примере выше квадратные скобки обозначают, что эти пункты опциональны, и мы можем запускать команду и с ними, и без них. Ниже я запустил разные варианты ls, чтобы продемонстрировать ее работу.

1. [email protected]: ls
2. bin Documents public_html
3. [email protected]:
4. [email protected]: ls -l
5. total 3
6. drwxr-xr-x  2 karpaff users 4096 Mar 23 13:34 bin
7. drwxr-xr-x 18 kapraff users 4096 Feb 17 09:12 Documents
8. drwxr-xr-x  2 karpaff users 4096 May 05 17:25 public_html
9. [email protected]:
10. [email protected]: ls /etc
11. a2ps.cfg aliases alsa.d cups fonts my.conf systemd
12. ...
13. [email protected]: ls -l /etc
14. total 3
15. -rwxr-xr-x  2 root root 123 Mar 23 13:34 a2ps.cfg
16. -rwxr-xr-x 18 root root 78 Feb 17 09:12 aliases
17. drwxr-xr-x  2 karpaff users 4096 May 05 17:25 alsa.d
18. ...
19. [email protected]:

Рассмотрим код по частям:

  • Строка 1 — запуск ls в базовой форме. Она вывела список содержимого текущей директории.
  • Строка 4 — запуск ls с ключом -l, который означает, что команда выведет длинный список. В длинном списке есть следующее:
    • Первый символ означает, является ли объект файлом - или директорией d.
    • Следующие 9 символов — типы разрешений для файла или директории.
    • Следующее поле — количество блоков (пока что не задумывайтесь об этом).
    • Дальше — владелец файла или директории (в данном случае — karpaff)
    • Дальше — группа, которой принадлежит файл или директория (в данном случае — users).
    • Следующая часть — размер файла/директории.
    • Затем идет время изменения.
    • И в конце — название файла или директории.
  • Строка 10 — запуск ls с аргументом командной строки /etc. Когда мы так делаем, ls выводит содержимое не рабочей директории, а той, которую мы передали в качестве аргумента.
  • Строка 13 — запуск ls и с ключом, и с аргументом командной строки. Соответственно, здесь был произведен вывод длинного списка директории /etc.
  • Строки 12 и 18 означают лишь, что для краткости я вырезал стандартный вывод некоторых команд. При запуске команд вы увидите более длинный список файлов и директорий.

Пути к файлам

При рассмотрении предыдущих команд мы затронули тему путей. Я хотел бы углубиться в эту тему, поскольку она важна для более эффективного использования Linux. Неважно, пытаемся мы обратиться к файлу или директории через командную строку, на самом деле мы обращаемся по пути. Путь — это способ добраться до конкретного файла или директории в системе.

Абсолютные и относительные пути

Существует два типа путей — абсолютные и относительные. Обращаемся мы к файлу или директории, мы будем использовать один из этих типов путей (система в любом случае будет направлена в правильное место).

Для начала нужно понять, что файловая система под Линуксом — это иерархическая структура. Наверху этой структуры находится корневая директория. Она обозначается одним слэшем /. У нее есть свои поддиректории, у них свои и так далее. Файлы могут находиться в любой из директорий.

Абсолютные пути указывают положение файла или директории относительно директории root. Их можно узнать по слэшу в начале пути /.

Относительные пути указывают положение файла или директории относительно ващего текущего местоположения в системе. Они не начинаются со слэша.

Пример:
1. [email protected]: pwd
2. /home/karpaff
3. [email protected]:
4. [email protected]: ls Documents
5. file1.txt file2.txt file3.txt
6. ...
7. [email protected]: ls /home/karpaff/Documents
8. file1.txt file2.txt file3.txt
9. ...
  • Строка 1 — запускаем pwd, чтобы узнать, где мы находимся.
  • Строка 4 — запускаем ls с аргументом в виде относительного пути. Documents — директория в той папке, в которой мы сейчас находимся. Такая команда может выдать разный результат в зависимости от того, где мы находимся. Если бы у нас был другой пользователь в системе, скажем, Вася, и мы запустили бы эту команду в его домашней директории, выводом стало бы содержимое папки Documents Васи.
  • Строка 7 — запускаем ls с аргументом в виде абсолютного пути. Вывод такой команды будет одинаков вне зависимости от того, где мы сейчас находимся.

Скоро вы увидите, что множество вещей в Linux можно получить несколькими разными способами. Пути — не исключение. Ниже приведены некоторые иные компоненты для построения путей. 

  • ~ (тильда) — обозначение вашей домашней директории. Например, если ваша домашняя директория /home/karpaff, то к директории Documents можно обратиться по пути /home/karpaff/Documents или по пути ~/Documents.
  • . (точка) — указание на директорию, где вы сейчас находитесь. Например, в примере выше на 4 строке мы обратились к директории Documents с помощью относительного пути. Тот путь можно было записать как ./Documents (Обычно в этом нет необходимости, но ниже мы рассмотрим примеры того, где это может пригодиться).
  • .. (две точки) — указание на родительскую директорию. Вы можете использовать такое сокращение в пути несколько раз, чтобы подниматься по иерархии. Например, если вы были в папке /home/karpaff, вы можете запустить команду ls ../../ и выводом будет список содержимого корневой директории.

Теперь вы знаете, что к местоположению можно обращаться множеством разных способов. Некоторые из вас зададутся вопросом, какой вариант лучше использовать? Ответ: любой, который больше нравится. Обращаетесь вы к файлу или директории, в командной строке вы обращаетесь по пути, а путь вы можете составить, используя любой из элементов, представленных выше. Лучший подход в этом деле — удобный именно для вас.

Примеры:
1. [email protected]: pwd
2. /home/karpaff
3. [email protected]:
4. [email protected]: ls ~/Documents
5. file1.txt file2.txt file3.txt
6. ...
7. [email protected]: ls ./Documents
8. file1.txt file2.txt file3.txt
9. ...
10. [email protected]: ls /home/ryan/Documents
11. file1.txt file2.txt file3.txt
12. ...
13. [email protected]:
14. [email protected]: ls ../../
15. bin boot dev etc home lib var
16. ...
17. [email protected]:
18. [email protected]: ls /
19. bin boot dev etc home lib var
20. ...

После того, как вы сами поиграетесь с этими командами в командной строке, вы станете лучше их понимать. Убедитесь, что понимаете, как работают элементы построения пути, поскольку мы будем использовать их в следующих уроках.

Как сменить директорию

Для передвижения по системе используется команда cd, сокращение от change directory (сменить директорию). Она работает следующим образом:

cd [местоположение]

Подсказка: если вы запустите команду без аргументов, она вернет вас в домашнюю директорию.

Команду cd можно запускать и без аргументов, как мы видели в подсказке выше, но обычно ее запускают с одним аргументом командной строки — месту, в которое мы хотим перейти. Место определяется абсолютным или относительным путем с использованием любых элементов для построения путей, упомянутых выше.

Пример:
1. [email protected]: pwd
2. /home/karpaff
3. [email protected]: cd Documents
4. [email protected]: ls
5. file1.txt file2.txt file3.txt
6. ...
7. [email protected]: cd /
8. [email protected]: pwd
9. /
10. [email protected]: ls
11. bin boot dev etc home lib var
12. ...
13. [email protected]: cd ~/Documents
14. [email protected]: pwd
15. /home/karpaff/Documents
16. [email protected]: cd ../../
17. [email protected]: pwd
18. /home
19. [email protected]: cd
20. [email protected]: pwd
21. /home/karpaff

Автодополнение

Прописывать пути вручную может быть утомительно. А если вы, как и я, постоянно опечатываетесь, то вам очень поможет маленький механизм командной строки под названием автодополнение.

Когда вы печатаете путь в командной строке, нажмите кнопку Tab, чтобы применить механизм автозавершения. Если ничего не произошло, значит существует несколько вариантов продолжения пути. Нажмите Tab снова, и вы увидите эти варианты. Продолжайте печатать и опять нажмите Tab, и механизм снова попытается завершить путь за вас.

Это сложно продемонстрировать в статье, так что попробуйте потестировать эту фичу сами. Если вы напечатаете в командной строке cd /hTab/<начало вашего имени пользователя>Tab, вы поймете, как это работает.

Что нужно запомнить

Команды

pwd
Выводит текущую директорию.

ls
Выводит писок содержимого директории.

cd
Переводит в другую директорию.

Понятия

Относительный путь
Местоположение файла или директории относительно вашего текущего местоположения в системе.

Абсолютный путь
Местоположение файла или директории относительно корневой папки файловой системы.

Практические задания

Давайте применим то, что мы только что узнали, на практике. Попробуйте выполнить следующие задания:

1. Начнем с передвижения по системе. Используйте команды cd и ls, чтобы больше узнать о директориях вашей системы и о том, что в них есть. Постарайтесь использовать разные варианты относительных и абсолютных путей. Интересные места для исследования:

/etc — здесь хранятся конфигурационные файлы системы.
/var/log — здесь хранятся файлы логов для разных системных программ. (У вас может не быть разрешений просматривать все в этой директории. Пусть это вас не останавливает. Пара сообщений об ошибках никому не помешает)
/bin — место, в котором хранятся некоторые часто используемые программы.
/usr/bin — еще одно место, в котором хранятся системные программы.

2. А теперь вернитесь в домашнюю директорию 4 разными способами.

3. Постарайтесь почаще использовать автодополнение. Зачем напрягаться, если компьютер может что-то делать за вас?

Все файлы в Linux имеют определенный адрес в файловой системе, с помощью которого мы можем получить к ним доступ с помощью файлового менеджера или консольных утилит. Это довольно простая тема, но у многих новичков с этим возникают трудности.

В сегодняшней небольшой заметке мы рассмотрим что такое путь к файлу Linux, каким он может быть, как правильно его писать и многое другое. Если раньше у вас возникали с этим трудности, то после прочтения статьи все станет полностью понятно.

Файловая система Linux очень сильно отличается от Windows. Мы не будем рассматривать ее структуру, это было сделано ранее. Мы сосредоточимся на работе с файлами.

Самое главное отличие, в том что адрес файла начинается не с диска, например, C: или D: как это происходит в Windows, а с корня, корневого системного каталога, к которому подключены все другие. Его адрес — /. И тут нужно сказать про адреса. Пути файлов linux используют прямой слеш «/» для разделения каталогов в адресе, и это отличается от того, что вы привыкли видеть в Windows — .

Например, если в Windows полный путь к файлу на рабочем столе выглядел C:UsersSergiyDesktop то в путь файла в linux будет просто /home/sergiy/desktop/. С этим пока все просто и понятно. Но проблемы возникают дальше.

В операционной системе Linux может быть несколько видов путей к файлу. Давайте рассмотрим какие бывают пути в linux:

  • Полный, абсолютный путь linux от корня файловой системы — этот путь вы уже видели в примере выше, он начинается от корня «/» и описывает весь путь к файлу;
  • Относительный путь linux — это путь к файлу относительно текущей папки, такие пути часто вызывают путаницу.
  • Путь относительно домашний папки текущего пользователя. — путь в файловой системе, только не от корня, а от папки текущего пользователя.

Рассмотрим теперь подробнее как выглядят эти пути в linux, а также разберем несколько примеров, чтобы было окончательно понятно. Для демонстрации будем пользоваться утилитой ls, которая предназначена для просмотра содержимого каталогов.

Например, у нас есть такой каталог в домашней папке с четырьмя файлами в нем:

ls

dir

Вот так будет выглядеть полный путь linux к одному из файлов:

ls /home/sergiy/tmp/file1

dir1

Это уже относительный путь linux, который начинается от домашней папки, она обозначается ~/. Заметьте, не ~, а именно ~/. Дальше вы уже можете указывать подпапки, в нашем случае tmp:

ls ~/tmp/file1

dir2

Ну или путь файла в linux, относительно текущей папки:

ls file1

В каждой папке есть две скрытые ссылки, мы сможем их увидеть с помощью ls, выполнив ее с параметром -a:

ls -a

dir3

Первая ссылка указывает на текущую папку (.), вторая (..) указывает на папку уровнем выше. Это открывает еще более широкие возможности для навигации по каталогам. Например, чтобы сослаться на файл в текущей папке можно использовать конструкцию:

./file1

dir4

Это бесполезно при просмотре содержимого файла. Но очень важно при выполнении программы. Поскольку программа будет сначала искаться в среде PATH, а уже потом в этой папке. А потому, если нужно запустить программу, которая находится в текущей папке и она называется точно также как и та что в каталоге /bin, то без явной ссылки что файл нужно искать в текущей папке ничего не получится.

Вторая ссылка вам позволяет получить доступ к файлам в папке выше текущей. Например:

ls ../tmp/file1

dir5

Такие конструкции могут довольно часто встречаться при компиляции программ. Все эти символы и пути файлов linux вы можете применять не только в терминале, но и в любом файловом менеджере, что может быть очень удобно.

Но терминал Linux предоставляет еще более широкие возможности. Вы можете использовать простые символы замены прямо в адресах файлов или каталогов. Например, можно вывести все файлы, начинающиеся на f:

ls ./f*

dir6

dir7

Или даже можно искать не только в папке tmp, а в любой подпапке домашней папки:

ls ~/*/f*

И все это будет работать, возможно, это не всегда нужно и практично. Но в определенных ситуациях может очень сильно помочь. Эти функции реализуются на уровне оболочки Bash, поэтому вы можете применять их в любой команде. Оболочка смотрит сколько файлов было найдено и для каждого из них вызывает команду.

Выводы

Вот и все. Теперь вы знаете все что необходимо, чтобы не только правильно написать путь к файлу linux, но и выполнять более сложные действия, например, поиск файлов или навигация по каталогам с помощью команды cd. Если у вас остались вопросы, спрашивайте в комментариях!

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

Об авторе

Основатель и администратор сайта losst.ru, увлекаюсь открытым программным обеспечением и операционной системой Linux. В качестве основной ОС сейчас использую Ubuntu. Кроме Linux, интересуюсь всем, что связано с информационными технологиями и современной наукой.

Понравилась статья? Поделить с друзьями:
  • Как найти подсказки с помощью пера геншин
  • Как найти точки между которыми разность потенциалов
  • Как найти ежемесячный платеж по кредиту формула
  • Как найти подругу для собаки
  • Как составить комментарий к тексту егэ