Как записать содержимое в файл на SFTP-сервере Linux с помощью SshClient? - PullRequest
0 голосов
/ 05 апреля 2019

Я работаю с SFTP-сервером Linux, используя код .Net (SshClient), поэтому я создаю папку на SFTP-сервере и создаю файлы.Для этого я использую следующий код,

using (var client = new SshClient(WebConfigurationManager.AppSettings["SftpServer"], WebConfigurationManager.AppSettings["SftpUserName"], WebConfigurationManager.AppSettings["SftpPassword"]))
{
   client.Connect();

    if (client.IsConnected)
    {
        //  Check if the Folder Already Exists 
        var ifExists = client.RunCommand("cat /etc/passwd  | grep -w " + ftpUserName);
        // If the Folder and User Does Not exists , create both 
        if (string.IsNullOrEmpty(ifExists.Result))
        {
            client.RunCommand("echo Asdf@123 | sudo -S mkdir /sftpusers/" + ftpUserName);
            client.RunCommand("echo Asdf@123 | sudo -S mkdir /sftpusers/" + ftpUserName + "/import"); //  this is for creating folder
            client.RunCommand("echo Asdf@123 | sudo -S mkdir /sftpusers/" + ftpUserName + "/schema");
            client.RunCommand("echo Asdf@123 | sudo -S touch /sftpusers/" + ftpUserName + "/schema/fileName.txt");
            sftpCreated = true;
        }
    }
    client.Disconnect();
}

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

client.RunCommand("echo Asdf@123 | sudo -S echo hi user >> /sftpusers/asb/schema/filename.txt");

Но это не работает.Я получаю сообщение об ошибке: Error = "bash: /sftpusers/asb/schema/filename.txt: Permission denied\n.

Меня немного смущает, что если одна и та же команда, например, echo pwd | sudo -s cmd создает папку, файлы на SFTP-сервере, то почему происходит сбой при записи содержимого в файл.

Нужна помощь по этому вопросу как можно раньше.

1 Ответ

3 голосов
/ 05 апреля 2019
sudo touch ./blabla

Создает файл blabla как root с правами root (!).Владельцем этого файла будет пользователь root, и, скорее всего, запись будет разрешена только для пользователя root.

sudo echo 123 > ./blabla

Это выполнит echo в качестве пользователя root и перенаправит вывод в blabla в качестве оболочки (!) пользователь.sudo заставляет команду echo запускаться от имени пользователя root.Но перенаправление > выполняется оболочкой, а не sudo.Таким образом, перенаправление выполняется открытой оболочкой, в вашем случае пользователем, не являющимся пользователем root, который не может получить доступ к файлу.

Вы должны записать файл в качестве пользователя root, чтобы онРабота.Вы можете запустить subshell от имени пользователя root:

echo 123 | sudo sh -c 'cat > ./blabla'
// or better for scripting, cause no double quoting is needed
echo 123 | sudo sh -c 'cat > "$1"' -- ./blabla

Это echo 123 и выполнение sh от имени пользователя root с помощью команды cat, перенаправленной на первый аргумент сценария, то есть blabla.Обратите внимание, что поскольку оболочка запускается от имени пользователя root, перенаправление также выполняется от имени пользователя root, поэтому оболочка может открывать и записывать в файл.

В качестве альтернативы, более чистый подход - сделать tee.

echo 123 | sudo tee blabla >/dev/null

Не забудьте перенаправить стандартный вывод tee на ноль, чтобы он ничего не печатал.

Do:

 client.RunCommand("echo Asdf@123 | sudo -S sh -c 'echo hi user >> "$1"' -- /sftpusers/asb/schema/filename.txt");

Обратите внимание, потому что выиспользуйте sudo -S для чтения пароля (что небезопасно и плохо), вы не можете использовать stdin для передачи записанной строки в tee.

...