Результат выполнения программы в слайс

Пользователь

от mark.akopian , в категории: Общие вопросы , год назад

Всем доброго вечераКак можно можно результат выполнения внешней программы(например, ping 8.8.8.8), которая запускается внутри func main() экспортировать в слайс? Если можно, с примером..спасибо!

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp Pocket

8 ответов

Администратор

от Stesha , год назад

@mark.akopian  Доброго вечера!

Вы можете выполнить внешнюю программу, такую как "ping", изнутри кода на Go и захватить её вывод в слайс. Для этого вы можете использовать пакет os/exec, который предоставляет инструменты для запуска внешних команд. Вот пример того, как это можно сделать:

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main


import (
	"fmt"
	"os/exec"
	"strings"
)


func main() {
	command := "ping"
	args := []string{"8.8.8.8"}


	cmd := exec.Command(command, args...)
	output, err := cmd.CombinedOutput() // Запуск команды и получение вывода


	if err != nil {
		fmt.Println("Ошибка при выполнении команды:", err)
		return
	}


	// Преобразование вывода в строку и разделение на строки
	outputString := string(output)
	lines := strings.Split(outputString, "\n")


	// Создание слайса строк для хранения результатов
	resultSlice := make([]string, 0)


	// Добавление строк из вывода в слайс
	for _, line := range lines {
		resultSlice = append(resultSlice, line)
	}


	// Вывод результатов
	fmt.Println("Результат выполнения команды:")
	for _, line := range resultSlice {
		fmt.Println(line)
	}
}


В этом примере комнда "ping" выполняется на IP-адресе "8.8.8.8". Вывод команды захватывается, разбивается на строки и затем добавляется в слайс. Вы можете настроить command и args для выполнения любой другой команды.

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

Пользователь

от mark.akopian , год назад

@Stesha Доброе утро! Спасибо за ответ!

А как правильно поступать с внешними программами? отдельно их запускать или делать отдельную функцию и запускать там? задача в реальности такая: получить список ip-адресов с aws (для этого используется консольная утилита aws), а потом распарсиить этот список для nginx и для fail2ban для добавления в whitelist. я думал это реализовать двумя функциями, условно func nginx() и func fail2ban(). Правильно ли передавать результат выполнения aws сразу в слайс или лучше сохранить в файл и потом с ним с работать? сейчас у меня работает сохранение в файл, но дальше я не понимаю как с ним работать. если работать с файлом, я никак не могу в инете найти пример как произвести замену строки с ключевым словом на то что хранится в файле. например, в файле jail.local найти слово ignoreip = и заменить это на то что в сохраненном файле. Спасибо!

Администратор

от Stesha , год назад

@mark.akopian  Доброе утро!


Ваш план с созданием двух функций (nginx() и fail2ban()) звучит разумно. Разделение логики на более мелкие и управляемые функции обычно делает код более читаемым и поддерживаемым.

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


Примерно так:

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main


import (
	"fmt"
	"os/exec"
	"strings"
)


func getAWSIPs() ([]string, error) {
	command := "aws"
	args := []string{"<ваш аргумент>"}


	cmd := exec.Command(command, args...)
	output, err := cmd.CombinedOutput()


	if err != nil {
		return nil, fmt.Errorf("ошибка при выполнении команды AWS: %s", err)
	}


	ipList := strings.Split(string(output), "\n")
	return ipList, nil
}


func nginx(ipList []string) {
	// Логика для работы с ipList и создания конфигурации для Nginx
}


func fail2ban(ipList []string) {
	// Логика для работы с ipList и создания конфигурации для Fail2Ban
}


func main() {
	awsIPs, err := getAWSIPs()
	if err != nil {
		fmt.Println(err)
		return
	}


	nginx(awsIPs)
	fail2ban(awsIPs)
}

Что касается замены строки в файле, вам нужно будет прочитать содержимое файла, найти нужную строку, заменить её и записать изменения обратно в файл. Вот пример:

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main


import (
	"fmt"
	"io/ioutil"
	"strings"
)


func replaceIgnoreIP(oldConfigPath string, newIgnoreIP string) error {
	content, err := ioutil.ReadFile(oldConfigPath)
	if err != nil {
		return err
	}


	newContent := strings.Replace(string(content), "ignoreip =", "ignoreip = "+newIgnoreIP, 1)


	err = ioutil.WriteFile(oldConfigPath, []byte(newContent), 0644)
	if err != nil {
		return err
	}


	return nil
}


func main() {
	oldConfigPath := "path/to/your/jail.local"
	newIgnoreIP := "your,new,ignore,ip,list"


	err := replaceIgnoreIP(oldConfigPath, newIgnoreIP)
	if err != nil {
		fmt.Println("Ошибка при замене строки:", err)
		return
	}


	fmt.Println("Строка успешно заменена.")
}

Пожалуйста, замените "path/to/your/jail.local" на фактический путь к вашему файлу jail.local, а также "your,new,ignore,ip,list" на новый список IP-адресов для ignoreip.

Пользователь

от mark.akopian , год назад

@Stesha 

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


 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package main

import (
    "fmt"
    "os"
    "os/exec"
    "strings"
)

func replaceIgnoreIP(oldConfigPath string, newIgnoreIP string) error {
    content, err := os.ReadFile(oldConfigPath)
    if err != nil {
       return err
    }

    newContent := strings.Replace(string(content), "ignoreip =", "ignoreip = "+newIgnoreIP, 1)

    err = os.WriteFile(oldConfigPath, []byte(newContent), 0644)
    if err != nil {
       return err
    }

    return nil
}

func main() {

    ipLocal := "x.x.x.x"

    command := "aws"
    args := []string{"ec2",
       "describe-instances",
       "--query=Reservations[*].Instances[*].PublicIpAddress",
       "--output=text",
    }

    cmd := exec.Command(command, args...)
    output, err := cmd.CombinedOutput() // Запуск команды и получение вывода

    if err != nil {
       fmt.Println("Ошибка при выполнении команды:", err)
       return
    }

    // Преобразование вывода в строку и разделение на строки
    outputString := string(output)
    lines := strings.Split(outputString, "\n")

    // Создание слайса строк для хранения результатов
    resultSlice := make([]string, 0)

    // Добавление строк из вывода в слайс
    for _, line := range lines {
       resultSlice = append(resultSlice, line)
    }
    resultSlice = append(resultSlice, ipLocal)

    // Вывод результатов
    fmt.Println("Результат выполнения команды:")
    for _, line := range resultSlice {
       fmt.Println(line)

    oldConfigPath := "jail.local"
    newIgnoreIP := resultSlice

    err1 := replaceIgnoreIP(oldConfigPath, newIgnoreIP)

    if err1 != nil {
       fmt.Println("Ошибка при замене строки:", err)
       return
    }

    fmt.Println("Строка успешно заменена.")

    }
}

Ошибка в этой части:

1
2
3
4
oldConfigPath := "jail.local"
newIgnoreIP := resultSlice

err1 := replaceIgnoreIP(oldConfigPath, newIgnoreIP)

я хотел добавить в jail.local содержимое слайса, но в err1 подчеркивается newIgnoreIP с ошибкой Cannot use 'newIgnoreIP' (type []string) as the type string. В логике ошибка или в синтаксисе? Спасибо!

Пользователь

от KotikGo , год назад

@mark.akopian  Ошибка возникает из-за того, что вы пытаетесь передать слайс строк ([]string) вместо одной строки (string) в качестве аргумента newIgnoreIP функции replaceIgnoreIP.


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

Если вы хотите добавить содержимое всего слайса строк в файл jail.local, вам нужно сначала преобразовать слайс в одну строку (например, с помощью strings.Join), а затем передать эту строку в функцию replaceIgnoreIP. Вот как это можно сделать:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Преобразование слайса строк в одну строку
newIgnoreIP := strings.Join(resultSlice, "\n")

err1 := replaceIgnoreIP(oldConfigPath, newIgnoreIP)

if err1 != nil {
    fmt.Println("Ошибка при замене строки:", err1)
    return
}

fmt.Println("Строка успешно заменена.")


Теперь newIgnoreIP будет иметь тип string, и ошибка больше не должна возникать.

Пользователь

от mark.akopian , год назад

@KotikGo 

Спасибо за ответ. Программа отработала, но в конце выдало: Ошибка при замене строки: <nil>

С чем это связано?

Пользователь

от mark.akopian , год назад

@KotikGo 

И еще вопрос.. если несколько раз запустить программу, то адреса не перезаписываются, а добавляются. как сделать так, чтобы обновлялись адреса в ignoreip? спасибо.

Пользователь

от mark.akopian , год назад

кто нибудь, ответьте, пожалуйста