Форум программистов, компьютерный форум, киберфорум
Rius
Войти
Регистрация
Восстановить пароль

Относительное зло или когда пути неисповедимы

Запись от Rius размещена 03.08.2018 в 08:24
Показов 34778 Комментарии 24

Часто встречаются такие и подобные вопросы:Объединяет их одно: автор проблемного кода использует относительные пути.

Что такое относительный путь? Это путь к файлу/каталогу (далее просто к файлу) в сокращённом виде, т.е. без корневого каталога или буквы диска. Например: ../file.txt или ./subdirectory/.
В противоложность, есть абсолютный путь (полные) вида /etc/network/interfaces (Linux, начинается с корневого каталога) или c:\Windows\System32\drivers\etc\hosts (Windows, начинается с буквы диска).

Для обращения к файлу, операционной системе требуется знать абсолютный путь.
Но если путь указан относительный, системе придётся самостоятельно приводить его к абсолютному. В этом случае вступает в игру другое понятие, известное под именами current directory и другими.
Это путь к каталогу, относительно которого производятся операции с относительными именами файлов (каталогов)
Вот на этом этапе и всплывает такое, что авторы:
  1. Вообще не задумываются об том, что и откуда берётся, указывая путь вида database.mdf, file.txt.
  2. Намеренно (но без понимания), указывают путь вида dir/file, ..dir/file, ../file, ./file и т.п., ошибочно полагая, что путь к файлу/каталогу будет отсчитываться от каталога, где находится программа.
  3. Намеренно (но c недопониманием), указывают путь вида current_directory + "/file.txt", ошибочно полагая, что current directory это каталог, где находится программа.
  4. ...
Взращивается такое ложное преставление поведением среды разработки по умолчанию (см. ниже).

При обращении из кода (нашей программы, чужой программы или функции ОС) к файлу по относительному пути, будет задействован current directory текущего процесса, чтобы получить абсолютный путь к файлу. Для упрощения, можно представлять это как конкатенацию строк - строкового значения current directory и строкового же значения относительного пути.
Увидеть значение current directory можно в:
  • Проводнике Windows, отображается в адресной строке;
  • Консоли Windows или Linux, отображается в строке приглашения к вводу (промпт);
  • Консоли Windows, выполнив команду
    Windows Batch file
    1
    
    cd
  • Консоли Linux, выполнив команду
    Bash
    1
    
    pwd

Демонстрация взаимодействия относительного пути и current directory
Пусть есть 2 файла
Code
1
2
R:\demo\1\file1.txt
R:\demo\2\file2.txt
И есть некая программа (наша или чужая), которой требуется обратиться к этим файлам.
Для демонстрации - программа more (консольная команда или утилита), принимающая путь к файлу и выводящая этот файл в консоль.
Проблема в этом случае идентична обращению к файлам из нашего кода. Т.к. всё равно
  • Есть указанный нами (относительный или абсолютный) путь к файлу;
  • Есть код, которому требуется обратиться к этому файлу;
  • Если указан относительный путь, его требуется привести к абсолютному.

Если мы находимся в каталоге R:\demo\1, т.е. current directory = R:\demo\1, программа может обратиться к файлу просто по имени, т.к. нужный файл находится в current directory:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
r:\demo\1>dir
 Содержимое папки r:\demo\1
 
03.08.2018  00:07    <DIR>          .
03.08.2018  00:07    <DIR>          ..
03.08.2018  00:10                11 file1.txt
               1 файлов             11 байт
               2 папок   2*038*804*480 байт свободно
 
r:\demo\1>more file1.txt
content 1
 
r:\demo\1>
Но для обращения к файлу в соседнем каталоге, надо указывать абсолютный путь, потому что просто имя файла уже не работает - такого файла в current directory нет:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
r:\demo\1>dir
 Содержимое папки r:\demo\1
 
03.08.2018  00:07    <DIR>          .
03.08.2018  00:07    <DIR>          ..
03.08.2018  00:10                11 file1.txt
               1 файлов             11 байт
               2 папок   2*038*804*480 байт свободно
 
r:\demo\1>more file2.txt
Не удается получить доступ к файлу R:\demo\1\file2.txt
 
r:\demo\1>more r:\demo\2\file2.txt
content 2
 
r:\demo\1>
К файлу в соседнем каталоге можно обратиться и проще - через относительный путь, указывая выход на каталог выше и оттуда вниз в соседний каталог:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
r:\demo\1>dir
 Содержимое папки r:\demo\1
 
03.08.2018  00:07    <DIR>          .
03.08.2018  00:07    <DIR>          ..
03.08.2018  00:10                11 file1.txt
               1 файлов             11 байт
               2 папок   2*038*804*480 байт свободно
 
r:\demo\1>more ..\2\file2.txt
content 2
 
r:\demo\1>
И это даже работает.

Но если current directory не совпадает (внезапно!) с предполагаемым положением, всё идёт не так:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
r:\demo\1>dir
 Содержимое папки r:\demo\1
 
03.08.2018  00:07    <DIR>          .
03.08.2018  00:07    <DIR>          ..
03.08.2018  00:10                11 file1.txt
               1 файлов             11 байт
               2 папок   2*038*804*480 байт свободно
 
r:\demo\1>cd r:\
 
r:\>more ..\2\file2.txt
Не удается получить доступ к файлу R:\2\file2.txt
 
r:\>more R:\demo\2\file2.txt
content 2
 
r:\>
В этом случае (если current directory не совпадает с ожидаемым) относительные пути перестают работать так, как ожидалось.
А вот абсолютные - продолжают работать, потому что на значение current directory они не опираются.


В ходе написания программы в соответствующей среде разработки никаких проблем обычно не замечается, потому что при запуске своей программы из среды разработки автор обычно получает current directory совпадающим с каталогом, куда собирается программа. Поэтому не возникает ни единой мысли о том, что в коде с относительными путями что-то не так.
А в ходе пробной эксплуатации, или при запуске иным способом, это не так расцветает во всей красе.

Почему? Потому что current directory это вовсе не каталог, где находится программа (внезапно!). Это текущий (т.е. активный в данный момент) каталог для процесса.
Они могут совпадать в какой-то момент времени, могут не совпадать, но это точно не одно и то же.

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

В этих случаях current directory тоже совпадает с каталогом, где расположена программа, и относительные пути отсчитываются относительно него.
Как только запуск производится в иных условиях, каковые как раз и встречены в упомянутых вверху темах, всё тут же перестаёт работать.

Решение: при обращении к файлам (в соответствующих методах), должны применяться только абсолютные пути, не относительные.
Это вовсе не значит, что надо их хардкодить, а путь к файлу, расположенному рядом с исполняемым, получить невозможно. Если понадобился путь относительно каталога программы, или любого иного каталога, нужно этот относительный путь привести программно к абсолютному.
Внимание: здесь говорится не об архитектуре приложения, а о том, что к моменту обращения к файлу, используемое значение пути должно быть абсолютным, чтобы никто (система или автор) не делал предположений о том, какой же именно путь надо будет применить, потому что реальность может разойтись с предположениями.
Когда именно абсолютный путь должен быть вычислен - уже иной вопрос (см. комменты ниже).
Проблемы возникают у тех, кто к указанному моменту (обращение к файлу) допустил значение с относительным путём.

В комментах кое-кто утверждает, что нужно пользоваться только относительными путями.
Пользоваться можно, только осторожно но не нужно. Этот способ применим только к месту (например, в консольных утилитах) и при условии хорошего понимания, как это всё работает и отчего может измениться значение current directory.
Пример того, к чему может привести

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

Данный конкретный баг взят из коммента Storm23. В новых версиях Windows исправлен, но можно наткнуться на что-то подобное.

Во избежание проблем, если всё-таки current directory требуется, лучше сохранить это значение в переменную при старте приложения и после, на её основе, формировать абсолютные пути по мере надобности.
Какие могут быть проблемы, помимо бага в ОС?
Например, некий код обработки файлов в каталоге был построен на использовании относительного пути. При попытке его использования в нескольких потоках для обработки независимых каталогов, возникнет проблема с тем, что значение current directory одно для процесса. С абсолютными же путями никаких проблем не будет.
Код надо писать так, чтобы возможностей ошибиться при его использовании было как можно меньше.
Путь к каталогу программы можно получить разными способами.
Примеры на C# .Net
  • C#
    1
    
    string path = AppDomain.CurrentDomain.BaseDirectory;
  • C#
    1
    
    string path = Path.GetDirectoryName(Application.ExecutablePath);
  • C#
    1
    2
    3
    4
    5
    6
    7
    8
    
    private string GetExeDirectory()
    {
      string codeBase = Assembly.GetExecutingAssembly().CodeBase;
      UriBuilder uri = new UriBuilder(codeBase);
      string path = Uri.UnescapeDataString(uri.Path);
      path = Path.GetDirectoryName(path);
      return path;
    }
  • ...

Пример на VB .Net

VB.NET
1
2
3
Public Function GetExeDir() As String
    GetExeDir = My.Application.Info.DirectoryPath
End Function

Пример на C++
C++
1
2
3
4
TCHAR exePath[MAX_PATH];
HMODULE hModule = GetModuleHandleW(NULL);
GetModuleFileNameW(hModule, exePath, MAX_PATH);
PathRemoveFileSpec(exePath);

Пример на Delphi
Delphi
1
2
3
4
5
6
7
var
  AppDir: string;
begin
  AppDir := ExtractFileDir(Application.ExeName);
  // Do something with AppDir, e.g.:
  ShowMessage(AppDir);
end;

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

Далее полученный абсолютный путь к каталогу программы надо сложить с относительным путём к файлу, чтобы получить абсолютный путь к искомому файлу.
Пример на C# .Net
C#
1
2
3
4
5
6
string exeDir = @"r:\demo\1"; // Путь к исходному каталогу
string relPath = @"..\2\file2.txt"; // Относительный путь к файлу
string resPath = Path.Combine(exeDir, relPath); // Объединяет две строки в путь.
Console.WriteLine(resPath);
resPath = Path.GetFullPath(resPath); // Возвращает для указанной строки пути абсолютный путь.
Console.WriteLine(resPath);
Результат:
r:\demo\1\..\2\file2.txt
r:\demo\2\file2.txt


Пример на VB .Net

VB.NET
1
2
3
4
5
6
7
8
9
10
Sub Main()
    Dim exeDir, relPath, resPath As String
 
    exeDir = "r:\demo\1" ' Путь к исходному каталогу
    relPath = "..\2\file2.txt" ' Относительный путь к файлу
    resPath = System.IO.Path.Combine(exeDir, relPath) ' Объединяет две строки в путь.
    Console.WriteLine(resPath)
    resPath = System.IO.Path.GetFullPath(resPath) ' Возвращает для указанной строки пути абсолютный путь.
    Console.WriteLine(resPath)
End Sub


Пример на C++

C++
1
2
3
4
5
6
7
8
9
10
TCHAR libraryPath[MAX_PATH] = { 0 };
_tcscat_s(libraryPath, MAX_PATH, exePath);
 
#ifdef _M_IX86
  _tcscat_s(libraryPath, MAX_PATH, TEXT("\\x86\\library.dll"));
#elif defined(_M_AMD64)
  _tcscat_s(libraryPath, MAX_PATH, TEXT("\\x64\\library.dll"));
#endif
 
LoadLibrary(libraryPath);
И уже вот этот, полученный программно абсолютный путь, нужно использовать там, где происходит обращение к файлу.

Почему, однако, можно запустить готовую программу типа notepad.exe или more.exe (что была в примере выше) без указания абсолютного пути?
Потому что для поиска программ есть такая системная переменная PATH. Поиск программ производится сначала в current directory, а если там не найдена - далее в каталогах, перечисленных в этой переменной.
Windows Batch file
1
2
3
4
5
6
7
r:\>echo %PATH%
C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\dotnet\;C:\Users\User\AppData\Local\Microsoft\WindowsApps
 
r:\>where more
C:\Windows\System32\more.com
 
r:\>
Поэтому программу можно запускать просто по имени, если она расположена в текущем каталоге или одном из указанных в переменной PATH. В иных случаях также следует (во избежание) формировать абсолютный путь.
Также, случается наличие в путях поиска нескольких исполняемых файлов с одинаковым именем. Тогда тоже помогает указание абсолютного пути, либо модификация порядка путей в %PATH% (что может потребовать админских прав или отрицательно повлиять на другие программы).

P.S. Немного об упомянутых в комментах эффектах:
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 24
Комментарии
  1. Старый комментарий
    Аватар для Usaga
    Это куда-нибудь в FAQ бы. Чтобы на глазах постоянно было.
    Запись от Usaga размещена 03.08.2018 в 09:08 Usaga вне форума
  2. Старый комментарий
    Аватар для OwenGlendower
    Цитата Сообщение от Usaga
    Это куда-нибудь в FAQ бы. Чтобы на глазах постоянно было.
    Это уже есть в FAQ. Правда в более кратком изложении - https://www.cyberforum.ru/csha... ost8862983

    Если у Rius есть желание выложить это в виде темы, то я перенесу её в прикрепленную тему по IO
    https://www.cyberforum.ru/csha... 63620.html
    Запись от OwenGlendower размещена 03.08.2018 в 10:11 OwenGlendower вне форума
  3. Старый комментарий
    Аватар для Rius
    Usaga, OwenGlendower, сия проблема относится не к одному какому-то языку, а ко многим (если не всем десктопным). Да и не только к языкам, но и к запуску готовых программ и их аргументам.
    Так что в каком-то определённом разделе писать... Просто ссылку добавьте, если хотите.
    Запись от Rius размещена 03.08.2018 в 10:25 Rius вне форума
  4. Старый комментарий
    Аватар для Evg
    Решение: пути должны быть только абсолютными, а не относительными
    Это слишком категоричный совет, если смотреть на него глобально. Многие могут понять его неправильно. При проектировании внутренней инфраструктуры программы все файлы должны описываться относительными путями, которые приклеиваются к некому базовому пути, который уже является абсолютным и вычисляется/настраивается один раз при старте программы
    Запись от Evg размещена 03.08.2018 в 14:49 Evg вне форума
  5. Старый комментарий
    Аватар для Rius
    Да.
    Речь о моменте самого обращения к файлу/каталогу. Вот тогда используемый путь должен быть уже абсолютным. Проблема возникает у тех, кто к этому моменту оставил относительный путь.
    Запись от Rius размещена 03.08.2018 в 15:33 Rius вне форума
  6. Старый комментарий
    Аватар для Evg
    Речь о моменте самого обращения к файлу/каталогу. Вот тогда используемый путь должен быть уже абсолютным
    Желательно в статье заострить на этом внимание, чтобы у читателей не возникало ошибочного понимания
    Запись от Evg размещена 03.08.2018 в 18:45 Evg вне форума
  7. Старый комментарий
    У меня тоже была такая проблема. В ярлыке подправил и всего делов
    Запись от TopLayer размещена 03.08.2018 в 18:50 TopLayer вне форума
  8. Старый комментарий
    Аватар для Rius
    Evg, добавил.
    TopLayer, а это то, что называется "костыли".
    Запись от Rius размещена 03.08.2018 в 19:15 Rius вне форума
  9. Старый комментарий
    Цитата Сообщение от Rius
    TopLayer, а это то, что называется "костыли".
    Задача заключалась в слежении за файлами определённой программы. Изначально я думал просто закинуть свой exe-шник в папку, куда установлена программа. Но когда обнаружил багу, понял, что теперь ничего никуда копировать не надо, а достаточно настроить ярлык. Короче говоря, два неверных решения уравновесили друг друга. Или это всё равно костыльно?
    Запись от TopLayer размещена 04.08.2018 в 18:26 TopLayer вне форума
  10. Старый комментарий
    Аватар для Rius
    Сами вот эти параметры совместимости со старыми приложениями, что настраиваются в ярлыках, являются костылями, призванными подпереть работу в новых ОС тех программ, что с неё работать нормально не умеют.
    У вас всё совпало, что никто никому не мешает, повезло.
    Но могло быть такое, что та определённая программа для своих нужд могла попытаться удалить или переименовать свой каталог (для обновления, например). И наличие другого процесса, имеющего current directory настроенным на этот каталог, заблокировало бы эту операцию. Вот такая не очевидная фича у Windows есть.
    Запись от Rius размещена 04.08.2018 в 19:17 Rius вне форума
  11. Старый комментарий
    Аватар для Storm23
    Можно также отметить, что в системах младше Windows7, текущая директория могла меняться прямо во время работы уже запущенной программы. Так вызов OpenFileDialog менял текущую директорию на директорию файла, который выбрал пользователь. Но в Windows7 это поведение было пофикшено.
    Запись от Storm23 размещена 26.08.2018 в 11:15 Storm23 вне форума
  12. Старый комментарий
    Аватар для Rius
    Да.
    Применительно к .Net Framework этот баг можно вернуть:
    Кликните здесь для просмотра всего текста
    C#
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    private void button1_Click(object sender, EventArgs e)
    {
        using (var dialog = new OpenFileDialog())
        {
            dialog.AutoUpgradeEnabled = false;
            dialog.RestoreDirectory = false;
     
            // Как только открылся диалог, в соседнем обработчике таймера вылетит исключение.
            if (dialog.ShowDialog() == DialogResult.OK)
            {
            }
        }
    }
     
    private void timer1_Tick(object sender, EventArgs e)
    {
        this.textBox1.AppendText(Directory.GetCurrentDirectory());
     
        try
        {
            string content = File.ReadAllText("TextFile1.txt");
            this.textBox1.AppendText(content);
        }
        catch(Exception exc)
        {
            this.textBox1.AppendText(exc.Message);
        }
    }

    Ещё одна причина не полагаться на относительные пути.
    Запись от Rius размещена 26.08.2018 в 11:31 Rius вне форума
  13. Старый комментарий
    Аватар для Agregat
    Правильная статья. Тоже жизнь научила в своих программах оперировать только абсолютными путями.
    Запись от Agregat размещена 26.08.2018 в 17:00 Agregat вне форума
  14. Старый комментарий
    Аватар для Avazart
    Почему? Потому что current directory это вовсе не каталог, где находится программа (внезапно!). Это текущий (т.е. активный в данный момент) каталог для процесса.
    Это не внезапно, это очевидно. И это даже не баг, а скорее фича, можно одну и туже программу запускать из разных директорий с разными настройками с помощью бат-файлов или ярлыков.

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

    Речь о моменте самого обращения к файлу/каталогу. Вот тогда используемый путь должен быть уже абсолютным
    Если не ошибаюсь это нужно лишь при работе с программами MS Word /Excel в остальных случаях это лишь лишние телодвижения.


    Можно также отметить, что в системах младше Windows7, текущая директория могла меняться прямо во время работы уже запущенной программы. Так вызов OpenFileDialog менял текущую директорию на директорию файла, который выбрал пользователь. Но в Windows7 это поведение было пофикшено.
    Если не подводит память это кажется настраивается в самом компоненте.

    Но да программа может поменять текущую директорию налету сама через SetCurrentDirectory(), но по очевидным причинам так не принято делать.
    Запись от Avazart размещена 26.08.2018 в 18:23 Avazart вне форума
  15. Старый комментарий
    Аватар для Rius
    Avazart эта фича очевидна для тех, кто умеет работать с консолью.
    Внезапно натыкающиеся на это явление, темы которых перечислены в начале, к таковым не относятся. Они ошибочно полагают, что Current Directory это просто тот каталог, где лежит программа. А это, внезапно для них, оказывается не так и программа не работает.
    Запись от Rius размещена 26.08.2018 в 18:29 Rius вне форума
  16. Старый комментарий
    Аватар для Avazart
    Avazart эта фича очевидна для тех, кто умеет работать с консолью.
    Если кто-то не умеет работать с консолью, то он ничего не умеет.

    А это, внезапно для них, оказывается не так и программа не работает.
    Это не повод отказываться от относительных путей, тут скорее всего нужно вернуться к истокам.
    Запись от Avazart размещена 26.08.2018 в 18:43 Avazart вне форума
  17. Старый комментарий
    Аватар для Rius
    Если не ошибаюсь это нужно лишь при работе с программами MS Word /Excel в остальных случаях это лишь лишние телодвижения.
    Применение полного пути устраняет данную проблему вообще.
    Применение относительного пути требует понимания, что такой текущий каталог, как он устанавливается и от чего может измениться. И если код или софт даже от понимающего автора, использующий относительные пути, попадёт в руки непонимающему пользователю, то он может перестать работать.
    Это всё равно что утверждать, что антивирусный софт не нужен, потому что пряморукость решает. Только вот пряморукость не столь распространена, как хотелось бы.
    Если кто-то не умеет работать с консолью, то он ничего не умеет.
    Данная запись как раз для тех, кто не умеет. Кто умеет, ему объяснять незачем.
    Это не повод отказываться от относительных путей, тут скорее всего нужно вернуться к истокам.
    И опять же, те, кто интересуются истоками, на такие грабли не наступят. А кто не интересуется - попробуй заставь. Хотите - напишите статью об истории возникновения current directory.
    Запись от Rius размещена 26.08.2018 в 19:00 Rius вне форума
  18. Старый комментарий
    Аватар для Avazart
    Применение полного пути устраняет данную проблему вообще.
    Какую проблему? Недостатка ума/знаний?
    Не думаю.

    Это всё равно что утверждать, что антивирусный софт не нужен, потому что пряморукость решает. Только вот пряморукость не столь распространена, как хотелось бы.
    А это все равно что поощрять дураков в их невежестве и чуть ли не уступать им место в транспорте.

    И опять же, те, кто интересуются истоками, на такие грабли не наступят. А кто не интересуется - попробуй заставь. Хотите - напишите статью об истории возникновения current directory.
    Ээ.. Вы предлагаете писать программы не имея даже приблизительного понятия что такое ОС ?

    Это не история это азы ОС да и можно погуглить https://ru.wikipedia.org/wiki/... 0%BE%D0%B3

    Т.е это понятие не только для винды существует.
    Запись от Avazart размещена 26.08.2018 в 19:04 Avazart вне форума
  19. Старый комментарий
    Аватар для Rius
    Какую проблему?
    Да хотя бы упомянутую Storm23:
    Кликните здесь для просмотра всего текста


    Вы хотите каждого новичка
    • научиться пользоваться консолью
    • понимать
      • что такое current directory;
      • откуда оно возникло;
      • как устанавливать и получать;
      • как оно может измениться без нашего участия;
      • как с этим правильно работать?
    А это все равно что поощрять дураков в их невежестве и чуть ли не уступать им место в транспорте.
    Так займитесь ими самостоятельно. Всё в ваших руках. Не надо мне это внушать, внушайте новичкам.
    Запись от Rius размещена 26.08.2018 в 19:18 Rius вне форума
  20. Старый комментарий
    Аватар для Avazart
    Да хотя бы упомянутую Storm23:
    Нет такой проблемы ибо XP мертва.

    Вы хотите каждого новичка

    научиться пользоваться консолью
    понимать
    что такое current directory;
    откуда оно возникло;
    как устанавливать и получать;
    как оно может измениться без нашего участия;
    как с этим правильно работать?
    Этого
    научиться пользоваться консолью
    Достаточно и само собой разумеется.
    Большая часть книг начинают обучение именно с написания консольных приложений.

    Касательно рабочего каталога нужно только погуглить и прочитать пару строчек:

    Текущий каталог

    Текущим называется каталог, с которым работает ОС, если ей не указать другого каталога. Он обозначается точкой (.).

    Для смены текущего каталога на другой используется команда cd; без указания целевого каталога она меняет каталог на домашний (в Unix-подобных ОС) или возвращает текущий (в Windows).
    https://ru.wikipedia.org/wiki/... 0%BE%D0%B3
    Запись от Avazart размещена 26.08.2018 в 19:22 Avazart вне форума
 
Новые блоги и статьи
BOINC: 22 года — и всё ещё работает
Programma_Boinc 12.03.2026
BOINC: 22 года — и всё ещё работает Дэвид Андерсон написал ретроспективу. Кратко: в 2001 году он ушёл из United Devices, где был CTO, и за несколько месяцев написал ядро BOINC — клиент, сервер,. . .
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru