LINUX.ORG.RU

Вопрос по go

 ,


0

3

Почему это не работает?

    out, err := exec.Command("find", "/etc" , "-type f").Output()
В аутпуте пусто, в err - «exit code 1». Если -type f убрать, то работает, с любым параметром после каталога поиска - нет.
go version go1.5.1 linux/amd64

Deleted

Ответ на: комментарий от feofan

Я думаю, слово «кавычит» не очень здесь корректно. Кавычки - это лишь синтаксис bash и других шеллов. На низком уровне через системный вызов передаётся массив, в котором "-type f" - единый элемент.

Deleted
()
Ответ на: комментарий от Kilte

Нда, ты прав. Но как-то это криво.

через системный вызов передаётся массив, в котором "-type f" - единый элемент.

Ну вот я интуитивно полагал что оно так, а значит должно быть одним параметром.

Deleted
()
Ответ на: комментарий от Deleted

При чем тут интуиция. man 2 execve. Каждый токен в отдельной null-term строке.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

Ну вот я интуитивно полагал что оно так

Оно так

а значит должно быть одним параметром.

А find ожидает, что -type и f отдельные элементы, а значит, не должно.

feofan ★★★★★
()
Ответ на: комментарий от Deleted

Ты интуитивно не прав. "-type" и «f» — это 2 разных параметра. Напиши маленькую программу на C выдающую свои argc и сам убедись в этом.

Но у меня вопрос в другом. «find» — это просто пример использования Command, или тебе в самом деле список файлов нужен?

Если так, то лучше использовать filepath.Walk: http://play.golang.org/p/Z2_OjQxLkF

beastie ★★★★★
()

попробуй не

    out, err := exec.Command("find", "/etc" , "-type f").Output()
, а
    out, err := exec.Command("find", "/etc" , "-type", "f").Output()

anonymous
()
Ответ на: комментарий от Deleted

На низком уровне через системный вызов передаётся массив, в котором "-type f" - единый элемент.

ой-ли! системному вызову фиолетово значение того *овна, что суется после команды на запуск. для него это всё - аргументы, которые каждый парсит как хочет и упаковывает в массив *char для execv. Просто принято, что даже совокупные параметры ("-opt optvalue") отправляются запускающим процессом и парсятся запускаемым по-отдельности. посему find не переварил твой "-type f" ибо в списке вариантов опций у него есть только "-type".

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от beastie

«find» — это просто пример использования Command, или тебе в самом деле список файлов нужен?

Может и нужен, но это в любом случае пример.
Просто решил пощупать го в качестве скриптового языка. Не понравилось. Declared and not used которые нельзя сделать ворнингами - это какой-то треш и концлагерь, нахер такое.

Deleted
()
Ответ на: комментарий от Deleted

в качестве скриптового языка

You're doing it wrong.

Declared and not used которые нельзя сделать ворнингами

Not a bug. Feature.

beastie ★★★★★
()
Ответ на: комментарий от Kilte

Наркоман.

Как будто это что-то плохое.
А питон чтобы взять - надо сперва положить.

Deleted
()
Ответ на: комментарий от Deleted

Подход «насрали, авось скомпилится» сам знаешь, к чему приводит. Уж лучше error, чем warning. Т.ч. свё правильно. Учись программировать чисто.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

Чисто. И с первого раза. И без единой ошибки.

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

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

В любой непонятной ситуации занимайся зряшной работой!

anonymous
()
Ответ на: комментарий от anonymous

Зряшную работу за тебя делает goimports (drop-in замена gofmt) подставляет imports, убирает лишние, форматирует. А компилятору можно и сказать, чтобы «не обращал внимания» на неиспользовунною переменную, использовав её. :)

_ = someVar
beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

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

package main

import "fmt"

func circleArea(r float64) float64 {
        //r := 1.5
        s := 3.14 * r * r
        d := 2 * r
        p := 3.14 * 2 * r

        fmt.Printf("r=%f, s=%f, d=%f, p=%f\n", r, s, d, p)

        return s
}

func main() {
        s := circleArea(1.5)
        fmt.Printf("Area=%f\n", s)
}

Потом тебе показалось: а вдруг функцию у меня тормозит именно вывод на экран? Закомментировал этот злосчастный Printf. В другом языке сразу бы проверил и увидел результаты.

Тут же еще трать время, чтобы увидеть затронутые переменные, написать _= d; _=p;. Или по своей инициативе, или по требованию компилятора. По компилятору — отвлекайся на сообщения лишний раз, по своему желанию — попадай в ситуацию, когда что-то не так понял, и получил лишнюю багу.

Если функция большая (а в go это часто бывает), то прыгай по коду туда-сюда в поисках объявлений и заглушек.

В общем, ничего, кроме головняка, эта фича не дает.

anonymous
()
Ответ на: комментарий от beastie

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

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

Вот тебе идиоматического go-кода, net/http/fs.go. Пример не 100% подходящий, но с вменяемыми допущениями идет.

Захотелось тебе вместо ranges вернуть константный массив, и на первой итерации тоже. В другом языке ставишь нужные return-ы вместо последних двух строчек, а тут — или возвращайся в начало, комменть объявление, или шамань с «_ = ranges».

А если таких переменных пара, то вообще весело будет.

// parseRange parses a Range header string as per RFC 2616.
func parseRange(s string, size int64) ([]httpRange, error) {
	if s == "" {
		return nil, nil // header not present
	}
	const b = "bytes="
	if !strings.HasPrefix(s, b) {
		return nil, errors.New("invalid range")
	}
	var ranges []httpRange
	for _, ra := range strings.Split(s[len(b):], ",") {
		ra = strings.TrimSpace(ra)
		if ra == "" {
			continue
		}
		i := strings.Index(ra, "-")
		if i < 0 {
			return nil, errors.New("invalid range")
		}
		start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])
		var r httpRange
		if start == "" {
			// If no start is specified, end specifies the
			// range start relative to the end of the file.
			i, err := strconv.ParseInt(end, 10, 64)
			if err != nil {
				return nil, errors.New("invalid range")
			}
			if i > size {
				i = size
			}
			r.start = size - i
			r.length = size - r.start
		} else {
			i, err := strconv.ParseInt(start, 10, 64)
			if err != nil || i > size || i < 0 {
				return nil, errors.New("invalid range")
			}
			r.start = i
			if end == "" {
				// If no end is specified, range extends to end of the file.
				r.length = size - r.start
			} else {
				i, err := strconv.ParseInt(end, 10, 64)
				if err != nil || r.start > i {
					return nil, errors.New("invalid range")
				}
				if i >= size {
					i = size - 1
				}
				r.length = i - r.start + 1
			}
		}
		ranges = append(ranges, r)
	}
	return ranges, nil
}
anonymous
()
Ответ на: комментарий от beastie

_ = someVar

Вот это леденящий душу пзц. Создали на ровном месте проблему, а потом прикрутили уродливый костыль для ее решения.

Учись программировать чисто.

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

Deleted
()
Ответ на: комментарий от beastie

Уж лучше error, чем warning.

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

Deleted
()
Ответ на: комментарий от Deleted

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

Ты только что это узнал?

The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt. – Rob Pike

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Да не, притерпеться можно.

Эту фишку сделали, чтобы ошибки случайно не зевнуть.

res, err = doStuff()

Не обработал err? Ты где-то накосячил, давай, исправляй.

res, _ = doStuff()

А тут явно написал, что с ошибками разбираться не собираешься.

Error-ы — такие же переменные, как и любые другие, так что проще запретить все неиспользованные переменные, чем городить дополнительный огород для ошибок.

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

Как показала практика, это просто неудобство, и не так сильно напрягающее.

Так что авторы golang крутые. А вот аргументация «я все сразу пишу правильно», «ворнинги нужны только быдлокодерам», «это не баг, а фича» очень не радует, это да.

anonymous
()
Ответ на: комментарий от Deleted

Чем меньше мест, где можно ошибиться, тем лучше. Поэтому и используются статическая сборка (никто не запустит с неправильной *.so-шкой), явные ошибки (не прилетит исключение непонятно с чего), единые настройки компилятора (не нужно громадного Makefile с кучей опций для ворнингов и оптимизаций).

Вот для сборки низкоуровневого кода на C++ часто нужны танцы с бубном, для сборки ruby-софта нужно пошаманить с версиями зависимостей, для питона/php/r часто нужен gcc правильной версии, чтобы собрать нативные модули. Тот же use strict в Javascript и Perl не просто так появился.

А в go для сборки достаточно команды go build, вот и думай, кто лучше программирует: то ли «ненормальные» голангеры, то «нормальные» программисты на других языках с управляемым компилятором.

anonymous
()
Ответ на: комментарий от Deleted

Гнилая отмазка Пайка. Типа это не он замшелый неосилятор, это пограмисты в гугле тупые. Ну да, ну да, поверим конечно, что гуголь нанимает школоту с похапе вместо образования. Реально деду давно пора на пенсию, го - это же какой-то позор.

anonymous
()
Ответ на: комментарий от anonymous

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

Если нужно коллекции крутить, то придется брать другой язык. Деревья/парсеры/мапредьюсы/макросы/жонглирование AST — все это не сюда.

А вот для сетевого асинхронного кода, для приложений с минимумом используемой памяти, или для быстрой консольной утилиты go подходит очень хорошо, за это и ценится.

anonymous
()
Ответ на: комментарий от anonymous

Конечно, одобряэ. Только никто в мире такого не осилил.

Попытался Rust, только что-то восторгов не слышно. В общем-то, на него и безо всяких каналов смотреть страшно. А go уже есть, он рулит и педалит, если дженерики не нужны.

anonymous
()

Из компилируемых для скриптинга лучше D, собирается примерно с той же скоростью, что и Go и на порядок быстрее плюсов. Сам код не очень быстрый, но для скриптинга это и не требуется.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.