Ошибка сценария оболочки; неожиданный [дубликат]

Члены класса:

Для деструктора pure virtual требуется реализация.

Объявление деструктора по-прежнему требует определения его (в отличие от обычной функции):

struct X
{
    virtual ~X() = 0;
};
struct Y : X
{
    ~Y() {}
};
int main()
{
    Y y;
}
//X::~X(){} //uncomment this line for successful definition

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

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

Это похоже на методы не virtual без определения, с добавлением аргументов, которые генерирует чистая декларация dummy vtable, и вы можете получить ошибку компоновщика без использования функции:

struct X
{
    virtual void foo();
};
struct Y : X
{
   void foo() {}
};
int main()
{
   Y y; //linker error although there was no call to X::foo
}

Чтобы это сработало, объявите X::foo() чистым:

struct X
{
    virtual void foo() = 0;
};

Non- virtual

Некоторые члены должны быть определены, даже если они явно не используются:

struct A
{ 
    ~A();
};

Следующие ошибки приведут к ошибке:

A a;      //destructor undefined

Реализация может быть встроенной в самом определении класса:

struct A
{ 
    ~A() {}
};

или снаружи:

A::~A() {}

Если реализация вне определения класса, но в заголовке, методы должны быть отмечены как inline, чтобы предотвратить множественное определение.

Все используемые методы-члены должны быть определены, если они используются.

Общей ошибкой является отказ от квалификации имени:

struct A
{
   void foo();
};

void foo() {}

int main()
{
   A a;
   a.foo();
}

Определение должно быть

void A::foo() {}

static. Члены данных должны быть определены вне класса в единственная единица перевода:

struct X
{
    static int x;
};
int main()
{
    int x = X::x;
}
//int X::x; //uncomment this line to define X::x

Инициализатор может быть предоставлен для элемента данных static const типа интеграла или перечисления в определении класса; однако odr-использование этого элемента по-прежнему потребует определения области пространства имен, как описано выше. C ++ 11 позволяет инициализировать внутри класса для всех членов static const данных.

14
задан user1837725 21 August 2013 в 22:06
поделиться

9 ответов

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

Y=1
while test "$Y" -le "20"
do
        echo "Number $Y"
        Y=$[Y+1]
done

И используя код с точкой с запятой с работающим чудом:

Y=1 ; while test "$Y" -le "20"; do echo "Number $Y"; Y=$[Y+1] ; done

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

0
ответ дан Benjamin W. 31 August 2018 в 16:36
поделиться

Вы можете решить эту проблему, не имея смешанных проблем с новой строкой (по крайней мере, в моей оболочке, которая является GNU bash v4.3.30):

#!/bin/bash
# foo.sh

function foo() {
    echo "I am quoting a thing `$1' inside a function."
}

while [ "$input" != "y" ]; do
    read -p "Hit `y' to continue: " -n 1 input
    echo
done

foo "What could possibly go wrong?"
$ ./foo.sh
./foo.sh: line 11: syntax error near unexpected token `done'
./foo.sh: line 11: `done'

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

$ echo "Command substitution happens inside double-quoted strings: `ls`"
Command substitution happens inside double-quoted strings: foo.sh
$ echo "..even with double quotes: `grep -E "^foo|wrong" foo.sh`"
..even with double quotes: foo "What could possibly go wrong?"

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

Я не очень конечно, почему это только дает одно сообщение об ошибке, но я думаю, что это связано с определением функции:

#!/bin/bash
# a.sh

function a() {
    echo "Thing's `quoted'"
}
a
while true; do
    echo "Other `quote'"
done
#!/bin/bash
# b.sh

echo "Thing's `quoted'"
while true; do
    echo "Other `quote'"
done
$ ./a.sh
./a.sh: line 10: syntax error near unexpected token `done'
./a.sh: line 10: `done'
$ ./b.sh
./b.sh: command substitution: line 6: unexpected EOF while looking for matching `''
./b.sh: command substitution: line 9: syntax error: unexpected end of file
Thing's quote'
./b.sh: line 7: syntax error near unexpected token `done'
./b.sh: line 7: `done'
0
ответ дан charliegreen 31 August 2018 в 16:36
поделиться

Какая ошибка вы получаете?

$ bash file.sh
test.sh: line 8: syntax error: unexpected end of file

Если вы получите эту ошибку, у вас могут быть неудачные окончания строк. Unix использует <LF> в конце файла, а Windows использует <CR><LF>. Этот символ <CR> интерпретируется как символ.

Вы можете использовать od -a test.sh, чтобы увидеть невидимые символы в файле.

$ od -a test.sh
0000000    #   !   /   b   i   n   /   b   a   s   h  cr  nl   #  sp  cr
0000020   nl   w   h   i   l   e  sp   :  cr  nl   d   o  cr  nl  sp  sp
0000040   sp  sp   e   c   h   o  sp   "   P   r   e   s   s  sp   [   C
0000060    T   R   L   +   C   ]  sp   t   o  sp   s   t   o   p   "  cr
0000100   nl  sp  sp  sp  sp   s   l   e   e   p  sp   1  cr  nl   d   o
0000120    n   e  cr  nl                                                
0000124

sp обозначает пробел, ht обозначает вкладку, cr обозначает <CR>, а nl обозначает <LF>. Обратите внимание, что все строки заканчиваются на cr, за которым следует символ nl.

Вы также можете использовать cat -v test.sh, если ваша команда cat принимает параметр -v.

Если у вас есть dos2unix на вашем поле, вы можете использовать эту команду для исправить файл:

$ dos2unix test.sh
4
ответ дан David W. 31 August 2018 в 16:36
поделиться

Открыть новый файл с именем foobar

nano -w foobar

Входной скрипт

 #!/bin/bash
 while [ 0 = 0 ]; do
   echo "Press [CTRL+C] to stop.."
   sleep 1
 done;

Выход и сохранение

CTRL + X, затем Y и Enter

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

chmod +x foobar
./foobar
1
ответ дан justbrowsing 31 August 2018 в 16:36
поделиться

Я получал ту же ошибку на Cygwin; Я сделал следующее (один из них исправил его):

  1. Конвертировано TABS в SPACES
  2. выполнено dos2unix в файле .(ba)sh
8
ответ дан Kunal B. 31 August 2018 в 16:36
поделиться

Иногда эта ошибка возникает из-за непредвиденных символов CR в файле, обычно потому, что файл был сгенерирован в системе Windows, которая использует окончания строки CR. Вы можете исправить это, выполнив os2unix или tr, например:

tr -d '\ 015' & lt; yourscript.sh> newscript.sh

Это удаляет из файла любые символы CR.

2
ответ дан Mihit Gandhi 31 August 2018 в 16:36
поделиться

Отредактируйте свой код в любой среде Linux, тогда вы не столкнетесь с этой проблемой. Если редактировать в блокнот Windows любое пространство, возьмите его как ^ M.

0
ответ дан santy 31 August 2018 в 16:36
поделиться

Может помочь кому-то еще: я столкнулся с такими же проблемами, когда я сделал некоторую «копию-вставку» из документа Microsoft Word, где я сделал заметки, для моего сценария оболочки.

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

Сначала было непонятно, я думаю, что скрытые символы и / или форматирование Word были проблемой. Очевидный, но не видимый ... Я потерял около часа на этом (я не эксперт в оболочке, как вы могли догадаться ...)

1
ответ дан sauna-l 31 August 2018 в 16:36
поделиться

Выполнить cat -v file.sh.

У вас, скорее всего, есть возврат каретки или свободное пространство в вашем файле. cat -v отобразит их как ^M и M-BM- или M- соответственно. Он также будет показывать любые другие странные символы, которые вы, возможно, попали в ваш файл.

Удалите разрывы строк Windows с помощью

tr -d '\r' file.sh > fixedfile.sh
19
ответ дан that other guy 31 August 2018 в 16:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: